菜鸟教程小白 发表于 2022-12-12 20:07:08

ios - NSURLSession 后台传输 : Callback for each video downloaded from a queue


                                            <p><p>我正在使用后台传输服务通过 <code>NSURLSession</code> 下载多个视频。当应用程序处于后台模式时下载工作正常并且我对此感到满意。我的问题是,我想要回调从队列中下载的每个视频。</p>

<p>我希望为每个下载的视频调用以下方法:</p>

<pre><code>-(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier
completionHandler:(void (^)())completionHandler
</code></pre>

<p>当系统在后台传输后没有更多消息发送到我们的应用程序时,以下方法:</p>

<pre><code>-(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
</code></pre>

<p>但是,当所有下载完成时,这两个方法都会被调用。
我放了 3 个视频供下载,然后将 App 放在后台。下载所有 3 个视频后调用这两种方法。</p>

<hr/>

<p>这是我在这些方法中所做的:</p>

<p><strong><em>AppDelegate</em></strong></p>

<pre><code>-(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier
completionHandler:(void (^)())completionHandler
{   
    self.backgroundTransferCompletionHandler = completionHandler;
}
</code></pre>

<p><strong><em>下载 ViewController </em></strong></p>

<pre><code>- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
{
    AppDelegate *appDelegate = (AppDelegate *)[ delegate];

    if (appDelegate.backgroundTransferCompletionHandler)
    {
      void (^completionHandler)() = appDelegate.backgroundTransferCompletionHandler;
      appDelegate.backgroundTransferCompletionHandler = nil;
      completionHandler();
    }

    NSLog(@&#34;All tasks are finished&#34;);
}
</code></pre>

<p>是否可以在下载每个视频时向用户显示本地通知?或者,我必须等到所有视频在后台完成下载? </p>

<p>如果答案是<strong>NO</strong>,那么我的问题是这两个不同回调的目的是什么?是什么将它们彼此分开? </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><blockquote>
<p>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 ?</p>
</blockquote>

<p>只有在与该 session 关联的所有下载完成后,应用程序才会在后台使用 <code>handleEventsForBackgroundURLSession</code> 重新启动,而不是一个接一个地重新启动。后台 session 的想法是最大程度地减少在后台运行(或反复启动然后暂停)所消耗的电池电量,而是让后台守护进程为您执行此操作,并让您知道一切何时完成。</p >

<p>理论上,您也许可以为每个 session 实例化一个单独的后台 session ,但这让我觉得这是对后台 session 的滥用(其目的是减少启动您的应用程序并在后台运行它所花费的时间)如果 Apple 不赞成这种做法,我也不会感到惊讶。它还需要一个笨拙的实现(具有多个 <code>NSURLSession</code> 对象)。</p>

<blockquote>
<p>If the answer is NO, then my question is what is the purpose of these two different callbacks ? What separates them from each other ?</p>
</blockquote>

<p>单独回调的目的是,一旦您的应用再次运行,它就可以为每次下载执行所需的任何后期处理(例如,将文件从临时位置移动到最终位置)。每次下载都需要单独的回调,即使在后台模式下重新启动应用程序时它们都被快速连续调用。另外,如果该应用恰好已经在前台运行,您可以在下载完成后处理各个下载。</p>

<hr/>

<p>顺便说一句,LombaX 是正确的,<code>handleEventsForBackgroundURLSession</code> 应该启动后台 session 。就个人而言,我将 <code>completionHandler</code> 作为 <code>NSURLSession</code> 对象的包装器的属性,因此 <code>handleEventsForBackgroundURLSession</code> 将实例化它(准备好调用其委托(delegate)方法),并将 <code>completionHandler</code> 保存在那里。这是保存完成处理程序的逻辑位置,无论如何您都必须实例化 <code>NSURLSession</code> 及其委托(delegate),并且它将 <code>URLSessionDidFinishEventsForBackgroundURLSession</code> 从需要返回到应用程序委托(delegate)中保存到获取保存的完成处理程序。</p>

<p>对或错,我的典型实现是将后台 NSURLSession 对象设为单例。因此我最终得到了类似的结果:</p>

<pre><code>- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {   
    .savedCompletionHandler = completionHandler;
}
</code></pre>

<p>一石二鸟,启动后台NSURLSession,保存<code>completionHandler</code>。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - NSURLSession 后台传输 : Callback for each video downloaded from a queue,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/37386786/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/37386786/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - NSURLSession 后台传输 : Callback for each video downloaded from a queue