【问题标题】:Network connection lost while switching from phone call to app从电话切换到应用程序时网络连接丢失
【发布时间】:2021-03-08 01:52:30
【问题描述】:

iOS 应用需要 IVR 电话才能完成验证。用户接听电话并返回应用程序继续。这之前工作得很好,但是,当用户从电话切换到应用程序时,最近开始出现网络连接丢失错误。我正在使用标准 NSURLSession 功能进行服务调用。应用程序使用 Soap 服务启动 IVR 呼叫并返回成功/失败响应。 错误日志:

[connection] nw_read_request_report [C2] 接收失败,错误“软件导致 连接中止”

任务 . HTTP 加载失败, 1807/0 字节(错误代码:-1005 [4:-4])任务 . 完成错误 [-1005] 错误域=NSURLErrorDomain 代码=-1005 “网络连接是 丢失。” UserInfo={_kCFStreamErrorCodeKey=-4, NSUnderlyingError=0x28086bd80 {错误域=kCFErrorDomainCFNetwork 代码=-1005 "(null)" UserInfo={NSErrorPeerAddressKey={长度= 16,容量= 16,字节= 0x100201bbc7676c180000000000000000},_kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask ., _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask ." ), NSLocalizedDescription=网络连接丢失。, NSErrorFailingURLStringKey=https://www.url?wsdl, NSErrorFailingURLKey=https://www.url?wsdl, _kCFStreamErrorDomainKey=4} 网络连接丢失。

在 iOS 13 及更高版本上对此进行了测试。似乎操作系统在一段时间内断开了网络连接,并且应用无法接收到 Web 服务的响应。

【问题讨论】:

  • 我有一些问题:它只发生在 3G/4G 上吗?它也发生在Wifi上吗?您的用户是否有 ESIM 并且仅将其用于网络?
  • 移动数据和 wifi 的结果相同。用户未使用 ESIM。
  • 好的,你能尝试在后台队列中运行并再次测试吗?
  • 你的意思是应该使用NSURLSession下载任务吗?后台执行,这里下载任务会比数据任务好?
  • 嗨,Nameet,我的意思是:stackoverflow.com/questions/24056205/…

标签: ios objective-c xcode background-process


【解决方案1】:

这里没有什么神秘之处。一旦您切换到另一个应用程序,该应用程序就会退出活动状态(并暂停,即没有 CPU 时间)。此外,一旦应用程序进入后台并保留其状态(如果已实现),操作系统就没有义务将其保存在内存中并且可以随时终止它。

连接(其操作系统部分、套接字等)在挂起时超时或在应用程序终止时断开连接。有一种后台任务方法可以在应用程序变为非活动状态之前完成一些绝对需要完成的事情。唯一的问题是,强烈建议不要使用超过 30-60 秒的后台任务,否则任务会被杀死。后台任务有超时,但可能会因版本而异。显然,您的情况不太适合后台任务,下载数据可能需要更长的时间并且您无法控制多长时间,您需要“服务”或“守护程序”之类的东西。不确定它们是否存在于 ios 中。

尝试阅读:iOS: Keep an app running like a service

要检查的另一件事是后台应用刷新。它允许应用不时唤醒并做一些有用的事情:https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/updating_your_app_with_background_app_refresh?language=objc

【讨论】:

    【解决方案2】:

    这在我的情况下有效: 在 AppDelegate 中。

    var backgroundUpdateTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier(rawValue: 0)
    func endBackgroundUpdateTask() {
        UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
        self.backgroundUpdateTask = UIBackgroundTaskIdentifier.invalid
    }
    func applicationWillResignActive(_ application: UIApplication) {
        self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
            self.endBackgroundUpdateTask()
        })
    }
    func applicationDidBecomeActive(_ application: UIApplication) {
        self.endBackgroundUpdateTask()
    
    }
    

    【讨论】:

      猜你喜欢
      • 2012-02-22
      • 2011-05-19
      • 2013-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多