3

更多的一般性问题 - 我不明白NSURLSession在“”中使用它时的工作原理background session mode。我将提供一些简单的人为示例代码。

我有一个保存对象的数据库 - 这样可以将部分数据上传到远程服务器。重要的是要知道上传了哪些数据/对象,以便准确地向用户显示信息。能够在后台任务中上传到服务器也很重要,因为该应用程序可以随时终止。

例如一个简单的个人资料图片对象:

@interface ProfilePicture : NSObject

@property int userId;
@property UIImage *profilePicture;
@property BOOL successfullyUploaded; // we want to know if the image was uploaded to out server - this could also be a property that is queryable but lets assume this is attached to this object

@end

现在假设我想将个人资料图片上传到远程服务器 - 我可以执行以下操作:

@implementation ProfilePictureUploader

-(void)uploadProfilePicture:(ProfilePicture *)profilePicture completion:(void(^)(BOOL successInUploading))completion
{
     NSUrlSession *uploadImageSession = ..... // code to setup uploading the image - and calling the completion handler;
     [uploadImageSession resume];
}

@end

现在我想在我的代码中的其他地方上传个人资料图片 - 如果成功更新 UI 和发生此操作的数据库:

ProfilePicture *aNewProfilePicture = ...;
aNewProfilePicture.profilePicture = aImage;
aNewProfilePicture.userId = 123;
aNewProfilePicture.successfullyUploaded = NO;

// write the change to disk
[MyDatabase write:aNewProfilePicture];

// upload the image to the server
ProfilePictureUploader *uploader = [ProfilePictureUploader ....];
[uploader uploadProfilePicture:aNewProfilePicture completion:^(BOOL successInUploading) {
  if (successInUploading) {
    // persist the change to my db.
    aNewProfilePicture.successfullyUploaded = YES;
    [Mydase update:aNewProfilePicture]; // persist the change 
  }
}];

现在很明显,如果我的应用程序正在运行,那么这个“ ProfilePicture”对象已成功上传并且一切都很好——数据库对象有自己的内部工作方式,包括数据结构/缓存等等。所有可能存在的回调都会被维护,并且应用程序状态很简单。

但我不清楚如果应用程序在上传过程中的某个时刻“死机”会发生什么。似乎任何回调/通知都已失效。根据 API 文档,上传由单独的进程处理。因此上传将继续,我的应用程序将在未来某个时候被唤醒以处理完成。但是对象“ aNewProfilePicture”此时不存在,所有回调/对象都消失了。我不明白此时存在什么上下文。我应该如何确保我的数据库和 UI 的一致性(例如更新该successfullyUploaded用户的“”属性)?我是否需要重新处理所有触及 DB 或 UI 的内容以与新 API 对应并在无上下文环境中工作?

4

1 回答 1

0

您可以使用具有后台配置的 NSURLSession 下载和上传文件。你必须实现 NSURLSessionDelegate、NSURLSessionDownloadDelegate、NSURLSessionUploadDelegate。使用后台会话,您不能再使用完成处理程序。我发现本教程对理解后台 NSURLSession 的工作方式非常有帮助:http: //www.appcoda.com/background-transfer-service-ios7/

在您的情况下,您可以执行以下操作:创建上传任务时,您可以将数据库中的用户 ID 分配给 NSURLSessionTask 的“taskDescription”属性。上传完成后,将调用委托方法,您可以实现如下内容:

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
   int userID = [task.taskDescription intValue];
   [self.database updateUserRecordWithID:userID];
}
于 2014-08-21T15:51:43.077 回答