当我的应用程序在后台运行时,我想使用 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问题,但它没有帮助。
保持任务队列的顶部
我发现,在后台,您应该避免让任务队列达到 0 个任务,直到您真正"完成"。相反,如果您始终在队列中保留少量任务,则可以获得更好的连续性。例如,当任务数量减少到 3 时,再添加 3 个。
专业提示:对于活动任务的计数,您最好使用自己的计数,而不是笨拙的异步-[NSURLSession getTasksWithCompletionHandler:]
。我将后台任务 ID(如 @(taskID)
)添加到 NSSet(例如 NSSet *activeTaskIDs
),并使用其中的计数。我在这里详细说明这一点。
括号异步调用
如果在didComplete...
回调期间执行任何异步操作,则必须将其与UIApplication
的-beginBackgroundTaskWithExpirationHandler:
和-endBackgroundTask:
括起来。否则,看起来你已经弹出了堆栈,iOS会杀死你。