ios - 我无法在全局队列(背景模式)上运行进程

标签 ios objective-c swift networking request

我在该代码中遇到问题,我想在后台发送请求并获得服务器确认的响应,一切正常。

即使用户阻止了他的iPhone,我也需要处理我的请求。
        有人可以帮忙吗?
        第一个问题:我编写的代码可以在后台模式下以某种方式工作吗?
        第二:如果不能,您能否解释一下我如何使用“ NSSessionConfiguration”中的Delegates和其他人员从服务器获得响应

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        [self REQUEST_METHOD];
});

最佳答案

您正沿着正确的背景NSURLSessionConfiguration走在正确的道路上。有关如何在后台会话中使用基于委托的实现的示例,请参见https://stackoverflow.com/a/32676536/1271826中的示例。



顺便说一句,通常来说,当您使用NSURLSession时,它总是异步运行。它从不阻塞主线程。因此,当我们看到NSURLSession代码分配到后台队列时(例如,在您的情况下,您使用了全局队列),这表明存在一些基本的误解。不需要dispatch_async

当然,如果请求的创建在计算上是昂贵的(例如,您需要在发送请求之前压缩一些视频或图像资产),那么可以将其分配到全局队列中。但是,如果您只是创建一个简单的JSON或x-www-form-urlencoded请求,则不需要将dispatch_async放入全局队列。当然NSURLSession不需要它。

因此,请勿混淆术语“背景”。该术语有三种完全不同的用法:


“后台” GCD队列是在主线程以外的其他线程上运行的队列(例如,全局队列是后台队列的类型)。
“后台” NSURLSessionConfiguration(或简称为“后台会话”)是由系统守护程序运行的,即使您的应用程序根本没有运行。您的应用可能不仅被暂停,而且甚至可能在其正常使用寿命期间被抛弃,但是该后台会话(由该系统守护程序运行)将继续运行。 (注意:如果您强制退出某个应用程序,则操作系统会将其解释为“用户希望杀死与该应用程序相关的所有内容,包括后台网络请求”,并将停止后台NSURLSession请求。)
应用程序本身的“后台”执行状态只是应用程序可能处于的几种可能状态/模式之一。它可以是:


“活动”(在前台运行);
“后台”(当用户离开应用程序时,它会退出其活动状态,并在挂起之前暂时过渡到在“后台”模式下运行几秒钟;此外,操作系统有时还可以唤醒挂起的应用程序,让其在此后台模式,然后再次暂停应用);
“已暂停”(该应用程序在内存中,但根本没有运行);和
“已终止”(例如,由于内存压力,该应用可能已被抛弃,将其从RAM中完全删除)。


About the Background Execution Sequence


因此,回到您的问题,当应用程序处于活动状态时,我们将创建一个后台会话并启动一些请求。如果用户离开该应用程序(最终将其转换为完全不运行的“暂停”状态),则后台会话中的请求将继续。完成NSURLSession任务后,即使用户正在使用其他应用程序,您的应用程序也可能在后台启动(根本没有显示UI),让该应用程序响应NSURLSession事件(由那些委托调用)方法),然后该应用将再次被暂停。而且,所有这些都可以在不将任何内容分发到全局队列的情况下发生。



请注意,运行背景NSURLSession并不是火箭科学,但通常需要重构我们的代码。您还会陷入并发症。例如,当您的应用重新启动时(尤其是如果它已在此中间时间段终止),您如何确定各种网络任务的状态并相应地更新UI。另外,这也很棘手,因为附加到我们的调试器会改变应用程序的生命周期,因此,当Xcode完全不运行时,您需要熟悉调试应用程序。例如,您可能使用统一消息传递并在macOS控制台上查看进度;有关更多信息,请参见Unified Logging and Activity Tracing视频和Unified Logging reference

因此,您可能想问自己是否绝对需要做所有这些事情。例如,如果您认为只需要一两分钟即可完成某些网络请求,则可以只要求操作系统在用户离开应用程序后让应用程序在后台最多运行3分钟。请参见Extending Your App’s Background Execution Time。它比背景NSURLSessionConfiguration容易得多。

此后台任务功能非常有限(例如,当前最多三分钟),但是如果这足以满足您的目的,那么它会简单得多。

关于ios - 我无法在全局队列(背景模式)上运行进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59342870/

相关文章:

ios - 如何循环遍历 UITableView 中尚未可见的单元格?

ios - 在 Swift/XCode 8 中从 subview 更改父 View ?

objective-c - 无法从文档 Controller 填充 NSMenu

javascript - 从 xcode 中的网页解析 javascript window.close() 函数

iphone - UIPageControl - iPhone 开发

ios - 如何使用 Firebase 和 Swift 将现有节点添加到具有不同父节点的另一个节点作为引用?

iOS:如何让容器 View 在隐藏内容标签时自动缩小其高度?

ios - 操作状态不是线程安全的 Swift

ios - 如何在 UISearchController 中自定义 searchBar?

swift - 列出 Vapor 中的所有路由