session-ios/SignalUtilitiesKit/OWSUploadOperation.m

111 lines
3.5 KiB
Objective-C

//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSUploadOperation.h"
#import "MIMETypeUtil.h"
#import "NSError+MessageSending.h"
#import "NSNotificationCenter+OWS.h"
#import "OWSDispatch.h"
#import "OWSError.h"
#import "OWSOperation.h"
#import <PromiseKit/PromiseKit.h>
#import "SSKEnvironment.h"
#import "TSAttachmentStream.h"
#import <SignalCoreKit/Cryptography.h>
#import <YapDatabase/YapDatabaseConnection.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN
NSString *const kAttachmentUploadProgressNotification = @"kAttachmentUploadProgressNotification";
NSString *const kAttachmentUploadProgressKey = @"kAttachmentUploadProgressKey";
NSString *const kAttachmentUploadAttachmentIDKey = @"kAttachmentUploadAttachmentIDKey";
// Use a slightly non-zero value to ensure that the progress
// indicator shows up as quickly as possible.
static const CGFloat kAttachmentUploadProgressTheta = 0.001f;
@interface OWSUploadOperation ()
@property (readonly, nonatomic) NSString *attachmentId;
@property (readonly, nonatomic) NSString *threadID;
@property (readonly, nonatomic) YapDatabaseConnection *dbConnection;
@end
#pragma mark -
@implementation OWSUploadOperation
- (instancetype)initWithAttachmentId:(NSString *)attachmentId
threadID:(NSString *)threadID
dbConnection:(YapDatabaseConnection *)dbConnection
{
self = [super init];
if (!self) {
return self;
}
self.remainingRetries = 4;
_attachmentId = attachmentId;
_threadID = threadID;
_dbConnection = dbConnection;
return self;
}
- (void)run
{
__block TSAttachmentStream *attachmentStream;
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
attachmentStream = [TSAttachmentStream fetchObjectWithUniqueID:self.attachmentId transaction:transaction];
}];
if (!attachmentStream) {
NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError();
// Not finding a local attachment is a terminal failure
error.isRetryable = NO;
[self reportError:error];
return;
}
if (attachmentStream.isUploaded) {
OWSLogDebug(@"Attachment previously uploaded.");
[self reportSuccess];
return;
}
[self fireNotificationWithProgress:0];
SNOpenGroup *publicChat = [LKStorage.shared getOpenGroupForThreadID:self.threadID];
NSString *server = (publicChat != nil) ? publicChat.server : SNFileServerAPI.server;
[[SNFileServerAPI uploadAttachment:attachmentStream withID:self.attachmentId toServer:server]
.thenOn(dispatch_get_main_queue(), ^() {
[self reportSuccess];
})
.catchOn(dispatch_get_main_queue(), ^(NSError *error) {
[self reportError:error];
}) retainUntilComplete];
}
- (void)fireNotificationWithProgress:(CGFloat)aProgress
{
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
CGFloat progress = MAX(kAttachmentUploadProgressTheta, aProgress);
[notificationCenter postNotificationNameAsync:kAttachmentUploadProgressNotification
object:nil
userInfo:@{
kAttachmentUploadProgressKey : @(progress),
kAttachmentUploadAttachmentIDKey : self.attachmentId
}];
}
@end
NS_ASSUME_NONNULL_END