简体   繁体   中英

Network connection lost while switching from phone call to app

iOS app needs IVR phone call to complete verification. The user answers phone call and returns to app to continue. This was working fine earlier, but, recently started getting network connection lost error when user is switching from phone call to app. I am using standard NSURLSession functionality for service call. App uses Soap service to start the IVR call and give a success/fail response back. Error logs:

[connection] nw_read_request_report [C2] Receive failed with error "Software caused connection abort"

Task <91526D5A-BF88-416A-B035-9441BA6CC550>.<1> HTTP load failed, 1807/0 bytes (error code: -1005 [4:-4]) Task <91526D5A-BF88-416A-B035-9441BA6CC550>.<1> finished with error [-1005] Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorCodeKey=-4, NSUnderlyingError=0x28086bd80 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x282592670 [0x1ddd28660]>{length = 16, capacity = 16, bytes = 0x100201bbc7676c180000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <91526D5A-BF88-416A-B035-9441BA6CC550>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <91526D5A-BF88-416A-B035-9441BA6CC550>.<1>" ), NSLocalizedDescription=The network connection was lost., NSErrorFailingURLStringKey=https://www.url?wsdl, NSErrorFailingURLKey=https://www.url?wsdl, _kCFStreamErrorDomainKey=4} The network connection was lost.

Tested this on iOS 13 and above. Seems like OS is disconnecting network connection for sometime and app fails to receive response of web service.

This worked in my case: In 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()

}

No mystery here. The app resigns active (and suspends, that is, gets no CPU time) as soon as you switch to another app. Moreover, once the app in the background and preserved its state (if implemented), the OS has no obligations to keep it in memory and can kill it anytime.

The connection (its OS part, socket, and so on) times out on suspend or disconnects on the app kill. There is an approach with background tasks to finish some things that absolutely need to be done before the app becomes inactive. The only thing is that it is strictly recommended not to use background tasks for something longer than 30-60 sec otherwise task gets killed. Background tasks have their timeouts but probably might change from version to version. Obviously, your case is not well suitable for background tasks, downloading data can take much longer and you cannot control how long, you need something like a "service" or "daemon". Not sure they exist in ios.

Try reading this: iOS: Keep an app running like a service

One more thing to check is the background app refresh. It allows the app to wake up from time to time and do something useful: 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM