2

当我的应用程序在后台时,我想使用NSURLSessionUploadTask.

使用适当配置NSURLSession的对象,排队后台上传的 API 是:

NSURLSessionUploadTask *dataTask = [sessionObj uploadTaskWithRequest:urlRequest
                                                            fromFile:localFilePath];
[dataTask resume];

当上传完成时——成功或失败——我在后台得到这个回调:

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error

在上述回调期间,我将另一个上传队列与
-uploadTaskWithRequest:fromFile:.

但是上传一些文件后,回调停止,上传也停止。

我是否缺少一些东西来保持上传?例如,我是否需要在这个回调中添加一些额外的代码来保持上传?

-(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
    AppDelegate *appDelegate = (id)[[UIApplication sharedApplication] delegate];
    if (appDelegate.backgroundSessionCompletionHandler) {
        void (^completionHandler)() = appDelegate.backgroundSessionCompletionHandler;
        appDelegate.backgroundSessionCompletionHandler = nil;
        completionHandler();
    } 
}

注意:我已经阅读了这个相关的 SO question,但它没有帮助。

4

1 回答 1

2

保持任务队列的顶部

I've found that, in the background, you should avoid letting the task queue reach 0 tasks until you are really "done". Instead, you get better continuity if you always keep few tasks in the queue at all times. For instance, when the number of tasks gets down to 3, add 3 more.

Protip: for a count of active tasks, you're better off with your own tally, rather than clumsy async -[NSURLSession getTasksWithCompletionHandler:]. I add/remove the background task ID (as @(taskID)) to an NSSet (e.g. NSSet *activeTaskIDs), and use the count from that. I spell this out here.

Bracket async calls

If you do anything async during the the didComplete... callback, you must surround that with UIApplication's -beginBackgroundTaskWithExpirationHandler: and -endBackgroundTask:. Otherwise, it looks like you've popped the stack, and iOS will kill you.

于 2014-02-10T18:27:24.320 回答