ios - 当我的应用程序进入前台时运行请求失败并显示 "The network connection was lost."

标签 ios swift appdelegate

在我从后台过渡到前台时开始发出请求后,我的应用程序出现了相当多的网络错误。
错误如下所示:

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.}
该代码是从我的应用程序的委托(delegate)触发的:
    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 state 意味着您无法与用户交互并且事件未传递。但是网络请求应该可以正常工作,对吧?知道为什么我的应用程序在不活动时无法运行请求吗?
    (我也考虑过使用 didBecomeActive 而不是 willEnterForeground ,但是当应用程序启动时它也会被调用,所以它并不是我真正需要的。)
    编辑:我也碰巧得到 Receive failed with error "Software caused connection abort"与此处讨论的问题无关的错误(即 Xcode 的多个版本):Xcode error connecting to simulator "Software caused connection abort"

    最佳答案

    我不知道您所描述的错误的根本原因,但我自己也遇到过。正如您所提到的,Apple 似乎在他们自己的系统将它们标记为前台之前告诉应用程序它们处于前台,因此在激活时立即发出的请求可能会被阻止(它经常发生但不是 100%根据我的经验)。
    对我有用的解决方案是简单地等待十分之一秒。
    您可以通过将您的电话包裹在 asyncAfter 中来做到这一点。称呼

    func applicationWillEnterForeground(_: UIApplication) {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { [weak self]
            self?.coordinator?.handleWillEnterForeground()
        }
    }
    
    但更优选的是,如果您的所有请求都通过一个协调器,请保留您的 AppDelegate 代码相同,而是让协调器查找返回错误代码 -1005 或 53 的请求,并让它等待十分之一秒,然后重试请求(确保有重试限制)。

    关于ios - 当我的应用程序进入前台时运行请求失败并显示 "The network connection was lost.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63621039/

    相关文章:

    ios - iOS 7在内部称为振动(已更改!)?

    ios - 自定义 UITableViewCell 的内容在编辑模式下被删除按钮重叠

    swift - 如何在 appDelegate 方法上设置计时器计划?

    ios - SetUbiquitous 对于不存在的文件显示 'file already exists'

    ios - 确定应用程序是否刚刚下载

    ios - Xcode 7.1 更新错误

    ios - 检测 iPhone 6 及 plus

    iphone - iOS书中奇怪的变量分配

    arrays - 尝试使数组中的特定索引不再是数组类型

    ios - Swift框架与Cocoapods——整合静态库