菜鸟教程小白 发表于 2022-12-12 15:42:44

iOS NSURLSession,如何在 didCompleteWithError 中重试


                                            <p><p>我想在我的服务器上尝试一个 post call 直到它成功,我想每 30 秒尝试一次。 </p>

<p>所以我在通话中使用 NSURLSession:</p>

<pre><code> NSURLSessionDownloadTask *task = ;
task.taskDescription = ];
;
</code></pre>

<p>然后如果发生错误(例如没有网络)我有一个错误:</p>

<pre><code>-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
</code></pre>

<p>我的问题是如何在 30 秒内执行相同的调用,我的应用会在后台运行吗?</p>

<p>我尝试了调度、NSThread 和 performSelector,但看起来它在后台不起作用:(</p>

<p>谢谢。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>一些观察:</p>
<ol>
<li><p>如果你想在几秒钟后重试,即使应用程序不再在前台,你可能只是想要求操作系统多一点时间来执行有限长度的任务。见 <a href="https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/extending_your_app_s_background_execution_time" rel="noreferrer noopener nofollow">Extending Your App&#39;s Background Execution Time</a> .如果您这样做,您的标准计时器 <code>dispatch_after</code> 或其他任何东西都应该可以正常工作。</p>
<p>请注意,您只有 30 秒(低于以前的 iOS 版本中的 3 分钟)来完成此后台任务。话虽如此,我个人怀疑如果用户没有连接,他们很可能在接下来的 30 秒内也没有连接,所以我不确定这个重试逻辑是否有任何好处如果应用没有运行。</p>
</li>
<li><p>顺便说一下,与其在 30 秒内重试,不如考虑 <a href="https://developer.apple.com/library/ios/samplecode/Reachability/Introduction/Intro.html" rel="noreferrer noopener nofollow">Reachability</a>以便在网络可用时通知您。在网络重新建立之前,再试是没有意义的。</p>
</li>
<li><p>另一种方法是使用<code>NSURLSessionConfiguration</code>的<code>backgroundSessionConfigurationWithIdentifier</code>。见 <a href="https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html#//apple_ref/doc/uid/TP40007072-CH4-SW5" rel="noreferrer noopener nofollow">Downloading Content in the Background</a> .如果您这样做,您有超过 3 分钟的时间来完成请求。一旦重新建立连接,它将自动启动。这种技术的缺点是(a)后台 session 不如前台 session 响应速度快; (b) 仅限于 iOS 7 及更高版本; (c) 你必须实现 <code>NSURLSession</code> 的基于委托(delegate)的再现,而不是完成 block 再现,这需要更多的工作。</p>
</li>
</ol>
<p>坦率地说,我通常倾向于采用第三种方法,但每种方法都有其优点。</p></p>
                                   
                                                <p style="font-size: 20px;">关于iOS NSURLSession,如何在 didCompleteWithError 中重试,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/31209372/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/31209372/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: iOS NSURLSession,如何在 didCompleteWithError 中重试