From 865d9d7b9611da60dd5ad1c9998bd9f69e7081c1 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 15 Mar 2017 10:17:41 -0300 Subject: [PATCH] Add "is uploaded" property to attachment streams. // FREEBIE --- src/Messages/Attachments/TSAttachment.h | 7 +++- src/Messages/Attachments/TSAttachment.m | 23 ++++++++---- src/Messages/Attachments/TSAttachmentStream.h | 3 ++ src/Messages/Attachments/TSAttachmentStream.m | 26 ++++++++++++- src/Messages/Interactions/TSOutgoingMessage.h | 8 ++++ src/Network/API/OWSUploadingService.h | 9 ++++- src/Network/API/OWSUploadingService.m | 37 ++++++++++++++----- 7 files changed, 90 insertions(+), 23 deletions(-) diff --git a/src/Messages/Attachments/TSAttachment.h b/src/Messages/Attachments/TSAttachment.h index 27e66b34c..67f1dd274 100644 --- a/src/Messages/Attachments/TSAttachment.h +++ b/src/Messages/Attachments/TSAttachment.h @@ -1,5 +1,6 @@ -// Created by Frederic Jacobs on 12/11/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// #import "TSYapDatabaseObject.h" @@ -19,6 +20,8 @@ NS_ASSUME_NONNULL_BEGIN encryptionKey:(NSData *)encryptionKey contentType:(NSString *)contentType; +- (void)upgradeFromAttachmentSchemaVersion:(NSUInteger)attachmentSchemaVersion; + @end NS_ASSUME_NONNULL_END diff --git a/src/Messages/Attachments/TSAttachment.m b/src/Messages/Attachments/TSAttachment.m index 286324090..c955fbff4 100644 --- a/src/Messages/Attachments/TSAttachment.m +++ b/src/Messages/Attachments/TSAttachment.m @@ -1,12 +1,13 @@ -// Created by Frederic Jacobs on 12/11/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// #import "TSAttachment.h" #import "MIMETypeUtil.h" NS_ASSUME_NONNULL_BEGIN -NSUInteger const TSAttachmentSchemaVersion = 2; +NSUInteger const TSAttachmentSchemaVersion = 3; @interface TSAttachment () @@ -40,7 +41,17 @@ NSUInteger const TSAttachmentSchemaVersion = 2; return self; } - if (_attachmentSchemaVersion < 2) { + if (_attachmentSchemaVersion < TSAttachmentSchemaVersion) { + [self upgradeFromAttachmentSchemaVersion:_attachmentSchemaVersion]; + _attachmentSchemaVersion = TSAttachmentSchemaVersion; + } + + return self; +} + +- (void)upgradeFromAttachmentSchemaVersion:(NSUInteger)attachmentSchemaVersion +{ + if (attachmentSchemaVersion < 2) { if (!_serverId) { _serverId = [self.uniqueId integerValue]; if (!_serverId) { @@ -48,10 +59,6 @@ NSUInteger const TSAttachmentSchemaVersion = 2; } } } - - _attachmentSchemaVersion = TSAttachmentSchemaVersion; - - return self; } + (NSString *)collection { diff --git a/src/Messages/Attachments/TSAttachmentStream.h b/src/Messages/Attachments/TSAttachmentStream.h index 9a3f9b329..8bd2b6a2b 100644 --- a/src/Messages/Attachments/TSAttachmentStream.h +++ b/src/Messages/Attachments/TSAttachmentStream.h @@ -23,6 +23,9 @@ NS_ASSUME_NONNULL_BEGIN // messages received from other clients @property (nullable, nonatomic) NSData *digest; +// This only applies for attachments being uploaded. +@property (atomic) BOOL isUploaded; + #if TARGET_OS_IPHONE - (nullable UIImage *)image; #endif diff --git a/src/Messages/Attachments/TSAttachmentStream.m b/src/Messages/Attachments/TSAttachmentStream.m index 98cf68548..a3dd9f364 100644 --- a/src/Messages/Attachments/TSAttachmentStream.m +++ b/src/Messages/Attachments/TSAttachmentStream.m @@ -1,5 +1,6 @@ -// Created by Frederic Jacobs on 17/12/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// #import "TSAttachmentStream.h" #import "MIMETypeUtil.h" @@ -20,6 +21,10 @@ NS_ASSUME_NONNULL_BEGIN _contentType = contentType; _isDownloaded = YES; + // TSAttachmentStream doesn't have any "incoming vs. outgoing" + // state, but this constructor is used only for new outgoing + // attachments which haven't been uploaded yet. + _isUploaded = NO; return self; } @@ -34,10 +39,27 @@ NS_ASSUME_NONNULL_BEGIN _contentType = pointer.contentType; _isDownloaded = YES; + // TSAttachmentStream doesn't have any "incoming vs. outgoing" + // state, but this constructor is used only for new incoming + // attachments which don't need to be uploaded. + _isUploaded = YES; return self; } +- (void)upgradeFromAttachmentSchemaVersion:(NSUInteger)attachmentSchemaVersion +{ + [super upgradeFromAttachmentSchemaVersion:attachmentSchemaVersion]; + + if (attachmentSchemaVersion < 3) { + // We want to treat any legacy TSAttachmentStream as though + // they have already been uploaded. If it needs to be reuploaded, + // the OWSUploadingService will update this progress when the + // upload begins. + self.isUploaded = YES; + } +} + #pragma mark - TSYapDatabaseModel overrides - (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction diff --git a/src/Messages/Interactions/TSOutgoingMessage.h b/src/Messages/Interactions/TSOutgoingMessage.h index 9751088fd..afc1ba463 100644 --- a/src/Messages/Interactions/TSOutgoingMessage.h +++ b/src/Messages/Interactions/TSOutgoingMessage.h @@ -12,9 +12,17 @@ NS_ASSUME_NONNULL_BEGIN @interface TSOutgoingMessage : TSMessage typedef NS_ENUM(NSInteger, TSOutgoingMessageState) { + // The message is either: + // a) Enqueued for sending. + // b) Waiting on attachment upload(s). + // c) Being sent to the service. TSOutgoingMessageStateAttemptingOut, + // The failure state. TSOutgoingMessageStateUnsent, + // The message has been sent to the service, but not received by any recipient client. TSOutgoingMessageStateSent, + // The message has been sent to the service, but not received by at least one recipient client. + // A recipient may have more than one client, and group message may have more than one recipient. TSOutgoingMessageStateDelivered }; diff --git a/src/Network/API/OWSUploadingService.h b/src/Network/API/OWSUploadingService.h index cfcdde659..8584121ba 100644 --- a/src/Network/API/OWSUploadingService.h +++ b/src/Network/API/OWSUploadingService.h @@ -1,5 +1,6 @@ -// Created by Michael Kirk on 10/18/16. -// Copyright © 2016 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// NS_ASSUME_NONNULL_BEGIN @@ -7,6 +8,10 @@ NS_ASSUME_NONNULL_BEGIN @class TSNetworkManager; @class TSAttachmentStream; +extern NSString *const kAttachmentUploadProgressNotification; +extern NSString *const kAttachmentUploadProgressKey; +extern NSString *const kAttachmentUploadAttachmentIDKey; + @interface OWSUploadingService : NSObject - (instancetype)init NS_UNAVAILABLE; diff --git a/src/Network/API/OWSUploadingService.m b/src/Network/API/OWSUploadingService.m index a73f53f68..a509f8804 100644 --- a/src/Network/API/OWSUploadingService.m +++ b/src/Network/API/OWSUploadingService.m @@ -12,6 +12,10 @@ NS_ASSUME_NONNULL_BEGIN +NSString *const kAttachmentUploadProgressNotification = @"kAttachmentUploadProgressNotification"; +NSString *const kAttachmentUploadProgressKey = @"kAttachmentUploadProgressKey"; +NSString *const kAttachmentUploadAttachmentIDKey = @"kAttachmentUploadAttachmentIDKey"; + @interface OWSUploadingService () @property (nonatomic, readonly) TSNetworkManager *networkManager; @@ -79,9 +83,11 @@ NS_ASSUME_NONNULL_BEGIN location:location attachmentId:attachmentStream.uniqueId success:^{ - DDLogInfo(@"%@ Uploaded attachment.", self.tag); + OWSAssert([NSThread isMainThread]); + + DDLogInfo(@"%@ Uploaded attachment: %p.", self.tag, attachmentStream); attachmentStream.serverId = serverId; - attachmentStream.isDownloaded = YES; + attachmentStream.isUploaded = YES; [attachmentStream save]; successHandler(); @@ -111,20 +117,18 @@ NS_ASSUME_NONNULL_BEGIN AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; + [self fireProgressNotification:0 attachmentId:attachmentId]; + NSURLSessionUploadTask *uploadTask; uploadTask = [manager uploadTaskWithRequest:request fromData:cipherText progress:^(NSProgress *_Nonnull uploadProgress) { - NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; - [notificationCenter postNotificationName:@"attachmentUploadProgress" - object:nil - userInfo:@{ - @"progress" : @(uploadProgress.fractionCompleted), - @"attachmentId" : attachmentId - }]; + [self fireProgressNotification:uploadProgress.fractionCompleted attachmentId:attachmentId]; } completionHandler:^(NSURLResponse *_Nonnull response, id _Nullable responseObject, NSError *_Nullable error) { + OWSAssert([NSThread isMainThread]); if (error) { + [self fireProgressNotification:0 attachmentId:attachmentId]; return failureHandler(error); } @@ -137,11 +141,26 @@ NS_ASSUME_NONNULL_BEGIN } successHandler(); + + [self fireProgressNotification:1 attachmentId:attachmentId]; }]; [uploadTask resume]; } +- (void)fireProgressNotification:(CGFloat)progress attachmentId:(NSString *)attachmentId +{ + dispatch_async(dispatch_get_main_queue(), ^{ + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter postNotificationName:kAttachmentUploadProgressNotification + object:nil + userInfo:@{ + kAttachmentUploadProgressKey : @(progress), + kAttachmentUploadAttachmentIDKey : attachmentId + }]; + }); +} + #pragma mark - Logging + (NSString *)tag