Allows retry of failed downloads.

This commit is contained in:
Frederic Jacobs 2015-02-19 01:04:32 +01:00
parent 9569a9b9c6
commit 19ca10d431
9 changed files with 96 additions and 23 deletions

View File

@ -110,7 +110,7 @@
NSString *identifier = [_knownNumbers objectAtIndex:[self knownNumbersIndexForIndexPath:indexPath]];
return [_associatedContactDict objectForKey:identifier];
} else {
NSAssert(NO, @"Trying to retreive contact from array at an index that is not a contact.");
NSAssert(NO, @"Trying to retrieve contact from array at an index that is not a contact.");
return nil;
}
}

View File

@ -71,7 +71,7 @@
}];
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
DDLogError(@"Failed to retreive the number of available prekeys.");
DDLogError(@"Failed to retrieve the number of available prekeys.");
}];
}
@ -85,7 +85,7 @@
[self clearSignedPreKeyRecordsWithKeyId:keyId];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
DDLogWarn(@"Failed to retreive current prekey.");
DDLogWarn(@"Failed to retrieve current prekey.");
}];
}

View File

@ -25,4 +25,8 @@
@property NSString *relay;
@property NSData *avatarOfGroupId;
@property (getter=isDownloading) BOOL downloading;
@property (getter=hasFailed) BOOL failed;
@end

View File

@ -18,7 +18,9 @@
self = [super initWithIdentifier:[[NSNumber numberWithUnsignedLongLong:identifier] stringValue] encryptionKey:key contentType:contentType];
if (self) {
self.relay = relay;
_failed = FALSE;
_downloading = FALSE;
_relay = relay;
}
return self;

View File

@ -7,7 +7,9 @@
//
#import "TSMessagesManager.h"
#import "TSAttachment.h"
@class TSAttachment;
@class TSAttachmentPointer;
@interface TSMessagesManager (attachments)
@ -18,4 +20,6 @@
inMessage:(TSOutgoingMessage*)outgoingMessage
thread:(TSThread*)thread;
- (void)retrieveAttachment:(TSAttachmentPointer*)attachment messageId:(NSString*)messageId;
@end

View File

@ -69,10 +69,13 @@ dispatch_queue_t attachmentsQueue() {
[self handleReceivedMessage:message withContent:content attachments:retrievedAttachments completionBlock:^(NSString *messageIdentifier) {
for (NSString *pointerId in retrievedAttachments) {
dispatch_async(attachmentsQueue(), ^{
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
TSAttachmentPointer *pointer = [TSAttachmentPointer fetchObjectWithUniqueID:pointerId transaction:transaction];
[self retrieveAttachment:pointer messageId:messageIdentifier];
__block TSAttachmentPointer *pointer;
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
pointer = [TSAttachmentPointer fetchObjectWithUniqueID:pointerId transaction:transaction];
}];
[self retrieveAttachment:pointer messageId:messageIdentifier];
});
}
}];
@ -87,7 +90,7 @@ dispatch_queue_t attachmentsQueue() {
NSDictionary *responseDict = (NSDictionary*)responseObject;
NSString *attachementId = [(NSNumber*)[responseDict objectForKey:@"id"] stringValue];
NSString *location = [responseDict objectForKey:@"location"];
TSAttachmentEncryptionResult *result =
[Cryptography encryptAttachment:attachmentData contentType:contentType identifier:attachementId];
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
@ -107,8 +110,6 @@ dispatch_queue_t attachmentsQueue() {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
result.pointer.isDownloaded = YES;
[result.pointer saveWithTransaction:transaction];
NSLog(@"finished uploading");
}];
[self sendMessage:outgoingMessage inThread:thread];
} else{
@ -130,6 +131,8 @@ dispatch_queue_t attachmentsQueue() {
- (void)retrieveAttachment:(TSAttachmentPointer*)attachment messageId:(NSString*)messageId {
[self setAttachment:attachment isDownloadingInMessage:messageId];
TSAttachmentRequest *attachmentRequest = [[TSAttachmentRequest alloc] initWithId:[attachment identifier]
relay:attachment.relay];
@ -137,14 +140,35 @@ dispatch_queue_t attachmentsQueue() {
if ([responseObject isKindOfClass:[NSDictionary class]]) {
dispatch_async(attachmentsQueue(), ^{
NSString *location = [(NSDictionary*)responseObject objectForKey:@"location"];
NSData *data = [self downloadFromLocation:location];
NSData *data = [self downloadFromLocation:location pointer:attachment messageId:messageId];
if (data) {
[self decryptedAndSaveAttachment:attachment data:data messageId:messageId];
}
});
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
DDLogError(@"Failed task %@ error: %@", task.description, error.description);
DDLogError(@"Failed retrieval of attachment with error: %@", error.description);
[self setFailedAttachment:attachment inMessage:messageId];
}];
}
- (void)setAttachment:(TSAttachmentPointer*)pointer isDownloadingInMessage:(NSString*)messageId {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[pointer setDownloading:YES];
[pointer saveWithTransaction:transaction];
TSMessage *message = [TSMessage fetchObjectWithUniqueID:messageId transaction:transaction];
[message saveWithTransaction:transaction];
}];
}
- (void)setFailedAttachment:(TSAttachmentPointer*)pointer inMessage:(NSString*)messageId {
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[pointer setDownloading:NO];
[pointer setFailed:YES];
[pointer saveWithTransaction:transaction];
TSMessage *message = [TSMessage fetchObjectWithUniqueID:messageId transaction:transaction];
[message saveWithTransaction:transaction];
}];
}
@ -157,6 +181,7 @@ dispatch_queue_t attachmentsQueue() {
TSAttachmentStream *stream = [[TSAttachmentStream alloc] initWithIdentifier:attachment.uniqueId
data:plaintext key:attachment.encryptionKey
contentType:attachment.contentType];
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[stream saveWithTransaction:transaction];
if([attachment.avatarOfGroupId length]!=0) {
@ -174,7 +199,7 @@ dispatch_queue_t attachmentsQueue() {
}
}
- (NSData*)downloadFromLocation:(NSString*)location {
- (NSData*)downloadFromLocation:(NSString*)location pointer:(TSAttachmentPointer*)pointer messageId:(NSString*)messageId{
__block NSData *data;
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
@ -182,14 +207,17 @@ dispatch_queue_t attachmentsQueue() {
[manager.requestSerializer setValue:@"application/octet-stream" forHTTPHeaderField:@"Content-Type"];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.completionQueue = dispatch_get_main_queue();
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[manager GET:location parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
data = responseObject;
dispatch_semaphore_signal(sema);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DDLogError(@"Failed to retreive attachment with error: %@", error.description);
DDLogError(@"Failed to retrieve attachment with error: %@", error.description);
if (pointer && messageId) {
[self setFailedAttachment:pointer inMessage:messageId];
}
dispatch_semaphore_signal(sema);
}];

View File

@ -47,6 +47,7 @@
#import "TSIncomingMessage.h"
#import "TSInteraction.h"
#import "TSAttachmentAdapter.h"
#import "TSAttachmentPointer.h"
#import "TSVideoAttachmentAdapter.h"
#import "TSMessagesManager+sendMessages.h"
@ -913,6 +914,7 @@ typedef enum : NSUInteger {
[self handleErrorMessageTap:(TSErrorMessage*)interaction];
break;
case TSInfoMessageAdapter:
[self handleWarningTap:interaction];
break;
case TSCallAdapter:
break;
@ -921,6 +923,31 @@ typedef enum : NSUInteger {
}
}
- (void)handleWarningTap:(TSInteraction*)interaction {
if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
TSIncomingMessage *message = (TSIncomingMessage*) interaction;
for (NSString *attachmentId in message.attachments) {
__block TSAttachment *attachment;
[self.editingDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction];
}];
if ([attachment isKindOfClass:[TSAttachmentPointer class]]) {
TSAttachmentPointer *pointer = (TSAttachmentPointer*)attachment;
if (!pointer.isDownloading) {
[[TSMessagesManager sharedManager] retrieveAttachment:pointer messageId:message.uniqueId];
}
}
}
}
}
-(void)moviePlayBackDidFinish:(id)sender {
DDLogDebug(@"playback finished");

View File

@ -115,13 +115,21 @@
}
}
else if ([attachment isKindOfClass:[TSAttachmentPointer class]]){
// can do loading information here
//TSAttachmentPointer *pointer = (TSAttachmentPointer*)attachment;
//TODO: Change this status when download failed;
adapter.messageBody = @"Attachment is downloading";
TSAttachmentPointer *pointer = (TSAttachmentPointer*)attachment;
adapter.messageType = TSInfoMessageAdapter;
if (pointer.isDownloading) {
adapter.messageBody = @"Attachment is downloading.";
} else {
if (pointer.hasFailed) {
adapter.messageBody = @"Attachment download failed, tap to retry.";
} else {
adapter.messageBody = @"New attachment queued for retrieval.";
}
}
} else {
DDLogError(@"We retreived an attachment that doesn't have a known type : %@", NSStringFromClass([attachment class]));
DDLogError(@"We retrieved an attachment that doesn't have a known type : %@", NSStringFromClass([attachment class]));
}
}
}

View File

@ -88,8 +88,8 @@
attachments:nil];
[newMessage saveWithTransaction:transaction];
TSIncomingMessage *retreived = [TSIncomingMessage fetchObjectWithUniqueID:[@(messageInt+50) stringValue] transaction:transaction];
XCTAssert(retreived.timestamp == uniqueNewTimestamp);
TSIncomingMessage *retrieved = [TSIncomingMessage fetchObjectWithUniqueID:[@(messageInt+50) stringValue] transaction:transaction];
XCTAssert(retrieved.timestamp == uniqueNewTimestamp);
}];
}