Swift URLSession 在应用进入后台时失败的问题

4
根据苹果公司的说明注意:您不必像本文所述那样使用后台会话来执行所有后台网络活动。声明适当的后台模式的应用程序可以使用默认URL会话和数据任务,就像它们在前台一样。
我正在尝试使用默认会话配置和代理(而不是完成处理程序)来使用我的DataTask,但是如果我按Home按钮并再次切换回应用程序,则我的数据任务总是失败:
Task <A25361F9-CAC0-4FA8-8663-777E1C6878A2>.<2> load failed with error Error Domain=NSPOSIXErrorDomain Code=53 "Software caused connection abort" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <A25361F9-CAC0-4FA8-8663-777E1C6878A2>.<2>, _kCFStreamErrorDomainKey=1, NSErrorPeerAddressKey=<CFData 0x108f07b40 [0x1db6c1420]>{length = 16, capacity = 16, bytes = 0x100201bb68118e240000000000000000}, _kCFStreamErrorCodeKey=53, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <A25361F9-CAC0-4FA8-8663-777E1C6878A2>.<2>"

我试过的方法:使用带或不带完成处理程序的共享会话,但出现了相同的问题。
我的问题是:这句话的意思是什么“声明适当的后台模式的应用程序可以使用默认的URL会话和数据任务”? 如何声明这些后台模式?
我遇到的唯一一件事是UIApplication.shared.beginBackgroundTask 这是苹果所说的“适当的后台模式”吗?还是我漏掉了什么?
谢谢。

不,那是正确的方法。您可以使用 beginBackgroundTask 来获得高达180秒的时间来完成您的任务。 - Paulw11
@Paulw11 我在文档中找不到180秒的数字,你确定是正确的吗? - akr
180秒是所有iOS应用程序可用的后台时间,但该值可能会在Apple发布新版本时更改(但现在已经是180秒了好几年);您唯一确定的是,您提供的“expirationHandler”将在您的应用程序耗尽时间之前不久被调用。如果在调用到期处理程序时不结束后台任务,则iOS将终止您的应用程序。 - Paulw11
你也可以使用backgroundTimeRemaining来查找剩余的后台时间;但需要注意的是,在Xcode下运行时,后台时间限制不会被执行。 - Paulw11
1个回答

6
是的,beginBackgroundTask(withName:expirationHandler:) 是请求操作系统在用户离开应用前给予应用完成请求的一些时间的正确方法。有关详细信息,请参见延长应用程序的后台执行时间

这就是苹果所谓的“适当的后台模式”吗?

他们指的是可能使应用程序在后台运行的任何技术。请参见后台执行序列说明。其中之一是“后台任务”,即使您的应用程序不再处于前台,您也会被赋予完成任务的有限时间之一。另一个是后台获取。如果启用了后台获取,则操作系统可能会自行决定在后台启动您的应用程序,让您执行请求,并在完成后调用完成处理程序(在这种情况下,您的时间甚至不到3分钟,可能只有30秒左右)。这是一种“适当的后台模式”的示例,您将使用标准/默认的URLSessionConfiguration而不是后台配置。苹果强调这一点,因为否则很容易假设任何与后台相关的网络请求都需要后台URLSessionConfiguration。但事实并非如此。
因此,如果您只是想让应用程序在用户按下主页按钮后继续运行一段时间以完成任务,则与标准的URLSession结合使用的beginBackgroundTask就足够了。或者,如果您正在使用其中一个“已批准的后台模式”(这似乎不是您的情况),那么同样,标准的URLSession就足够了。
后台URLSession确实适用于那些请求可能超过分配时间的情况。也许您正在下载许多非常大的资产,例如电影,可能需要超过几分钟的时间。只有在这种情况下,您才需要使用后台URLSessionConfiguration.background(withIdentifier:)。这取决于请求需要花费的时间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接