我正在使用后台传输服务通过 NSURLSession 下载多个视频。当应用程序处于后台模式时下载工作正常并且我对此感到满意。我的问题是,我想要回调从队列中下载的每个视频。
我希望为每个下载的视频调用以下方法:
-(void)applicationUIApplication *)application handleEventsForBackgroundURLSessionNSString *)identifier
completionHandlervoid (^)())completionHandler
当系统在后台传输后没有更多消息发送到我们的应用程序时,以下方法:
-(void)URLSessionDidFinishEventsForBackgroundURLSessionNSURLSession *)session
但是,当所有下载完成时,这两个方法都会被调用。
我放了 3 个视频供下载,然后将 App 放在后台。下载所有 3 个视频后调用这两种方法。
这是我在这些方法中所做的:
AppDelegate
-(void)applicationUIApplication *)application handleEventsForBackgroundURLSessionNSString *)identifier
completionHandlervoid (^)())completionHandler
{
self.backgroundTransferCompletionHandler = completionHandler;
}
下载 View Controller
- (void)URLSessionDidFinishEventsForBackgroundURLSessionNSURLSession *)session
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (appDelegate.backgroundTransferCompletionHandler)
{
void (^completionHandler)() = appDelegate.backgroundTransferCompletionHandler;
appDelegate.backgroundTransferCompletionHandler = nil;
completionHandler();
}
NSLog(@"All tasks are finished");
}
是否可以在下载每个视频时向用户显示本地通知?或者,我必须等到所有视频在后台完成下载?
如果答案是NO,那么我的问题是这两个不同回调的目的是什么?是什么将它们彼此分开?
Best Answer-推荐答案 strong>
Is it possible to show user a local notification on downloading of each video ? Or, I will have to wait til all videos complete downloading in the background ?
只有在与该 session 关联的所有下载完成后,应用程序才会在后台使用 handleEventsForBackgroundURLSession 重新启动,而不是一个接一个地重新启动。后台 session 的想法是最大程度地减少在后台运行(或反复启动然后暂停)所消耗的电池电量,而是让后台守护进程为您执行此操作,并让您知道一切何时完成。
理论上,您也许可以为每个 session 实例化一个单独的后台 session ,但这让我觉得这是对后台 session 的滥用(其目的是减少启动您的应用程序并在后台运行它所花费的时间)如果 Apple 不赞成这种做法,我也不会感到惊讶。它还需要一个笨拙的实现(具有多个 NSURLSession 对象)。
If the answer is NO, then my question is what is the purpose of these two different callbacks ? What separates them from each other ?
单独回调的目的是,一旦您的应用再次运行,它就可以为每次下载执行所需的任何后期处理(例如,将文件从临时位置移动到最终位置)。每次下载都需要单独的回调,即使在后台模式下重新启动应用程序时它们都被快速连续调用。另外,如果该应用恰好已经在前台运行,您可以在下载完成后处理各个下载。
顺便说一句,LombaX 是正确的,handleEventsForBackgroundURLSession 应该启动后台 session 。就个人而言,我将 completionHandler 作为 NSURLSession 对象的包装器的属性,因此 handleEventsForBackgroundURLSession 将实例化它(准备好调用其委托(delegate)方法),并将 completionHandler 保存在那里。这是保存完成处理程序的逻辑位置,无论如何您都必须实例化 NSURLSession 及其委托(delegate),并且它将 URLSessionDidFinishEventsForBackgroundURLSession 从需要返回到应用程序委托(delegate)中保存到获取保存的完成处理程序。
对或错,我的典型实现是将后台 NSURLSession 对象设为单例。因此我最终得到了类似的结果:
- (void)applicationUIApplication *)application handleEventsForBackgroundURLSessionNSString *)identifier completionHandler:(void (^)())completionHandler {
[BackgroundSession sharedSession].savedCompletionHandler = completionHandler;
}
一石二鸟,启动后台NSURLSession,保存completionHandler 。
关于ios - NSURLSession 后台传输 : Callback for each video downloaded from a queue,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/37386786/
|