Jac*_*ery 5 objective-c background-process ios nsurlsession nsurlsessionconfiguration
我已经实现了一个针对iOS 7+的下载管理器应用程序NSURLSession.下载管理器具有要按优先级顺序下载的排队文件列表.当应用程序处于后台并且委托调用被正确调用时,下载工作正常.但是当应用程序进入后台时,即使下载完成,也需要花费太多时间
NSURLSession delegate:- **URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL
被叫.有时代理人根本没有被调用,当我来到前台时,会调用下载任务委托.这种延迟的原因是什么?
小智 0
我遇到了一个非常类似的问题,后台任务会启动,但随后似乎暂停。当应用程序返回前台时,任务就会完成。
我通过记录来自的输出来验证情况是否如此-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
我发现解决这个问题的方法是如何存储、处理和执行完成处理程序。
就我而言,该过程开始于
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
[self.fmStore performBackgroundRefresh:^(UIBackgroundFetchResult result) {
//Set application badge if new data is available
if (result==UIBackgroundFetchResultNewData) [UIApplication sharedApplication].applicationIconBadgeNumber++;
completionHandler(result);
}];
}
Run Code Online (Sandbox Code Playgroud)
远程通知启动下载过程。
管理下载的方法返回一个值,具体取决于新数据的可用性
-(void)performBackgroundRefresh:(void (^)(UIBackgroundFetchResult))completion{
if(newData) completion(UIBackgroundFetchResultNewData);
else completion(UIBackgroundFetchResultNoData);
}
Run Code Online (Sandbox Code Playgroud)
此时它返回到存储完成处理程序的ApplicationDelegate
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{
//Store completion handler for background session
self.sessionCompletionHandler=completionHandler;
}
Run Code Online (Sandbox Code Playgroud)
最后,执行这段代码,调用完成处理程序并创建适当的通知
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
[session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
if (![downloadTasks count]) {
FM_AppDelegate *appDelegate=(FM_AppDelegate *)[[UIApplication sharedApplication] delegate];
if (appDelegate.sessionCompletionHandler) {
void (^completionHandler)() = appDelegate.sessionCompletionHandler;
appDelegate.sessionCompletionHandler = nil;
completionHandler();
}
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"ContentRefreshNotification" object:Nil];
}];
}
}];
}
Run Code Online (Sandbox Code Playgroud)
在我的例子中,这个来回过程发生,因为 NSURLSession 存在于作为 ApplicationDelegate 属性的对象中。如果您将 NSURLSession 实现为 ApplicationDelegate 本身的属性,那么所有这些代码都将存在于同一个文件中。
希望这会有所帮助,但如果您需要更多信息,请参阅这两个教程1和2,因为我的代码基于我在其中阅读的内容。
| 归档时间: |
|
| 查看次数: |
1640 次 |
| 最近记录: |