斯威夫特 |后台线程中的网络调用立即超时
Posted
技术标签:
【中文标题】斯威夫特 |后台线程中的网络调用立即超时【英文标题】:Swift | Network call in background thread timing out instantly 【发布时间】:2021-06-08 22:28:33 【问题描述】:每当应用程序收到新的静默通知时,我都会配置一个本地网络调用,它会触发 setAction(),它是一个 POST 请求,将与刚刚收到的通知相关的信息发送到我们自己的服务器,在前台,网络调用的工作方式为预期,仅当应用程序处于后台时才会出现问题。我 100% 确定 setAction 正在被调用,但 它看起来像在它启动 dataTask 时网络调用超时,我尝试使用线程,但我不确定问题就在那里。
注意事项:
为了确保不是网络问题,我还尝试了其他 HTTP 请求调用配置
如果我快速发送 2 个静默通知,它会触发 1 个 setAction()
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
// Network call
tellMe.setAction()
completionHandler(UIBackgroundFetchResult.newData)
我已经能够检索到的一些“日志”(真实的 https URL 被隐藏起来,例如)。
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=_kCFStreamErrorCodeKey=-2103, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <92F80B2F-3D6A-4089-AC76-D160B584712C>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <92F80B2F-3D6A-4089-AC76-D160B584712C>.<1>"
), NSLocalizedDescription=The request timed out., NSErrorFailingURLStringKey=https://actualURL.com, NSErrorFailingURLKey=https://actualURL.com, _kCFStreamErrorDomainKey=4
The request timed out.
提前谢谢大家,
【问题讨论】:
您在网络请求完成之前呼叫completionHandler
。这告诉操作系统可以再次暂停您的应用程序。推迟这个调用,直到你的网络请求完成(但一定要在 30 秒内调用它,否则会发生坏事)。
【参考方案1】:
问题在于,completionHandler 在 http 请求甚至有时间被调用之前就被调用了。解决方法是增加更多时间,如下所示(不是最漂亮的实现,但它有效),
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
// Network call
tellMe.setAction()
let state = UIApplication.shared.applicationState
if state == .background
//print("App in Background")
DispatchQueue.main.asyncAfter(deadline: .now() + 29)
completionHandler(UIBackgroundFetchResult.newData)
else
//print("App in Foreground or Active")
completionHandler(UIBackgroundFetchResult.newData)
【讨论】:
您可以避免等待整个 29 秒:创建一个 dispatch_group 并存储它,例如作为应用程序委托的属性。在进行网络调用之前进入组(dispatch_group_enter...),让网络调用在成功或失败时离开调度组,并且 dispatch_group_wait(在 bg 线程上)超时为 29,并调用完成处理程序以上是关于斯威夫特 |后台线程中的网络调用立即超时的主要内容,如果未能解决你的问题,请参考以下文章