ios - 在 iOS 应用终止时处理 Alamofire 请求

标签 ios alamofire application-lifecycle

AppDelegate.applicationWillTerminate 在应用程序即将终止时被调用。在此功能中,我通过 Alamofire 发出网络请求,以通知服务器该应用程序正在终止。 Alamofire 的响应处理程序永远不会被调用。在我看来,终止在调用完成处理程序之前完成。

Alamofire 的完成处理程序似乎在主线程上运行。我发现文档说该应用程序负责耗尽主队列:“虽然您不需要创建主调度队列,但您确实需要确保您的应用程序适本地耗尽它。有关如何管理此队列的更多信息,请参阅在主线程上执行任务。” (来自 https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html)这就是我被困的地方。

如何排出主线程?我需要确保最后一个 Alamofire 请求在主线程退出之前运行。

最佳答案

不要担心“耗尽”主线程。问题比这更简单。这只是当您的应用程序离开“前台”/“事件”状态时如何做某事的问题。

当用户离开您的应用去做其他事情时,应用通常不会终止。它进入“挂起”状态,保留在内存中但不执行任何代码。因此,当该应用程序暂停时,它无法处理您的请求(但该应用程序也尚未终止)。

有两种方法可以解决这个问题。

  1. 您可以请求一点时间来完成您的请求(参见 Extending Your App's Background Execution Time )。通过这样做,您的应用不会暂停,而是暂时进入“后台”状态,在此状态下可以继续执行一小段时间。

    这种方法的优点是过程相当简单。只需在开始请求之前获取后台任务 ID,然后告诉它后台任务已在 Alamofire 完成处理程序中完成。

    这种方法的缺点是您只有 30 秒(以前是 3 分钟)来处理请求。如果连接良好,这通常就足够了。但是,如果您在那段时间没有良好的网络连接,请求可能永远不会发送。

  2. 第二种方法稍微复杂一些:您可以使用后台 URLSession 发出请求。在这种情况下,您实际上是在告诉 iOS 接管此请求的处理,操作系统将继续这样做,即使您的应用已挂起(或稍后在其自然生命周期中终止)。

    但这比我概述的第一种方法要复杂得多,并且在此过程中您会失去 Alamofire 的轻松和优雅。您可以自己动手去做(参见 https://stackoverflow.com/a/26542755/1271826 的示例),但它与您习惯使用 Alamofire 的明显和直观的界面相去甚远。例如,您不能使用简单的 response/responseJSON 完成处理程序。您只能下载/上传任务(无数据任务)。您必须编写代码来处理操作系统重新启动您的应用程序以告诉您网络请求已发送(即使您没有对此响应做任何有意义的事情)。等等

    但这种更复杂的方法的优点是它更健壮。此过程没有 3 分钟的限制。每当重新建立连接时,操作系统仍会代表您发送请求。您的应用甚至可能会在那个时间点终止,操作系统仍会代表您发送请求。

请注意,这两种方法都不能处理“强制退出”(例如,用户双击主页按钮并向上滑动以终止应用程序)。它只是处理应用程序正常正常离开以去做其他事情。

关于ios - 在 iOS 应用终止时处理 Alamofire 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46505146/

相关文章:

ios - 使用 SpriteKit 开发着色器

ios - 如何使用 arc4random 从数组中选择随机 SKShapeNode?

javascript - React 生命周期方法顺序

javascript - MonkeyTalk IDE Javascript 文件中变量的记录值

android - 在服务器上托管 Android 操作系统

swift - 如何使用 alamofire 发送此参数

ios - AlamoFire 发送 Nil

swift - 在快速包装时意外发现 nil

android - Activity.finish() 方法到底在做什么?

javascript - 子组件如何在不监听生命周期方法的情况下从父组件接收 props?