当我的应用进入前台时请求 运行 失败并显示 "The network connection was lost."
Requests run when my app will enter foreground fail with "The network connection was lost."
在我从后台过渡到前台时开始发出请求后,我的应用出现了相当多的网络错误。
错误如下所示:
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x2808e85a0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x282550410 [0x1f80cb728]>{length = 16, capacity = 16, bytes = 0x10021068c0a8010a0000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://192.168.1.10:4200/api/users/sessions, NSErrorFailingURLKey=http://192.168.1.10:4200/api/users/sessions, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-4, NSLocalizedDescription=The network connection was lost.}
代码是从我的应用程序的委托中触发的:
func applicationWillEnterForeground(_: UIApplication) {
coordinator?.handleWillEnterForeground()
}
并且从 this documentation 开始,现阶段应允许网络请求:
At launch time, the system starts your app in the inactive state before transitioning it to the foreground. Use your app’s launch-time methods to perform any work needed at that time. For an app that is in the background, UIKit moves your app to the inactive state by calling one of the following methods:
- For apps that support scenes — The sceneWillEnterForeground(_:) method of the appropriate scene delegate object.
- For all other apps — The applicationWillEnterForeground(_:) method.
When transitioning from the background to the foreground, use these methods to load resources from disk and fetch data from the network.
此外:
- 如果我进入后台仅 1 秒,网络请求将成功(当完成处理程序被调用时,应用程序状态将是
active
)
- 如果我等待超过 5 秒,网络请求将出错(调用完成处理程序时应用程序状态将是
inactive
)
根据我的理解,inactive
状态意味着您无法与用户交互并且事件未被传送。但是网络请求应该可以正常工作,对吧?知道为什么我的应用程序在不活动时不能 运行 请求吗?
(我也考虑过使用 didBecomeActive
而不是 willEnterForeground
,但它也会在应用程序启动时被调用,所以这并不是我真正需要的。)
编辑:我也碰巧遇到了与此处讨论的问题无关的 Receive failed with error "Software caused connection abort"
错误(即 Xcode 的多个版本):
我不知道您描述的错误的根本原因,但我自己 运行 已经解决了。正如您提到的那样,Apple 似乎在自己的系统将它们标记为前台之前就告诉应用程序它们位于前台,因此在激活后立即发出的请求可能会被阻止(这种情况经常发生,但不是 100%我的经验时间)。
对我有用的解决方案是等待十分之一秒。
您可以通过将您的电话包装在 asyncAfter
电话
中来做到这一点
func applicationWillEnterForeground(_: UIApplication) {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { [weak self]
self?.coordinator?.handleWillEnterForeground()
}
}
但更好的是,如果您的所有请求都通过一个协调器,请保持您的 AppDelegate 代码不变,而是让协调器查找 return 错误代码为 -1005 或 53 且具有 它等待十分之一秒然后重试请求(一定要有重试限制)。
在我从后台过渡到前台时开始发出请求后,我的应用出现了相当多的网络错误。
错误如下所示:
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x2808e85a0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x282550410 [0x1f80cb728]>{length = 16, capacity = 16, bytes = 0x10021068c0a8010a0000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://192.168.1.10:4200/api/users/sessions, NSErrorFailingURLKey=http://192.168.1.10:4200/api/users/sessions, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-4, NSLocalizedDescription=The network connection was lost.}
代码是从我的应用程序的委托中触发的:
func applicationWillEnterForeground(_: UIApplication) {
coordinator?.handleWillEnterForeground()
}
并且从 this documentation 开始,现阶段应允许网络请求:
At launch time, the system starts your app in the inactive state before transitioning it to the foreground. Use your app’s launch-time methods to perform any work needed at that time. For an app that is in the background, UIKit moves your app to the inactive state by calling one of the following methods:
- For apps that support scenes — The sceneWillEnterForeground(_:) method of the appropriate scene delegate object.
- For all other apps — The applicationWillEnterForeground(_:) method.
When transitioning from the background to the foreground, use these methods to load resources from disk and fetch data from the network.
此外:
- 如果我进入后台仅 1 秒,网络请求将成功(当完成处理程序被调用时,应用程序状态将是
active
) - 如果我等待超过 5 秒,网络请求将出错(调用完成处理程序时应用程序状态将是
inactive
)
根据我的理解,inactive
状态意味着您无法与用户交互并且事件未被传送。但是网络请求应该可以正常工作,对吧?知道为什么我的应用程序在不活动时不能 运行 请求吗?
(我也考虑过使用 didBecomeActive
而不是 willEnterForeground
,但它也会在应用程序启动时被调用,所以这并不是我真正需要的。)
编辑:我也碰巧遇到了与此处讨论的问题无关的 Receive failed with error "Software caused connection abort"
错误(即 Xcode 的多个版本):
我不知道您描述的错误的根本原因,但我自己 运行 已经解决了。正如您提到的那样,Apple 似乎在自己的系统将它们标记为前台之前就告诉应用程序它们位于前台,因此在激活后立即发出的请求可能会被阻止(这种情况经常发生,但不是 100%我的经验时间)。
对我有用的解决方案是等待十分之一秒。
您可以通过将您的电话包装在 asyncAfter
电话
func applicationWillEnterForeground(_: UIApplication) {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { [weak self]
self?.coordinator?.handleWillEnterForeground()
}
}
但更好的是,如果您的所有请求都通过一个协调器,请保持您的 AppDelegate 代码不变,而是让协调器查找 return 错误代码为 -1005 或 53 且具有 它等待十分之一秒然后重试请求(一定要有重试限制)。