When the app goes into the background, it wants to make a single request, unfortunately it receives the error:
sessionTaskFailed (error: Error Domain = NSURLErrorDomain Code = -1005 "The network connection was lost...")
Code:
override func viewDidLoad() {
super.viewDidLoad()
notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
}
@objc func appMovedToBackground() {
let URL: String = "http://www.test.com/"
AF.request(URL, method: .post, parameters: parameters, headers: headers)
.responseJSON { [] response in
switch response.result {
case .success(let data):
print(data)
case .failure(let error):
print(error)
}
}
}
CodePudding user response:
Looks like you should implement the background task. The Apple documentation gives an example of how to do it:
func sendDataToServer( data : NSData ) {
// Perform the task on a background queue.
DispatchQueue.global().async {
// Request the task assertion and save the ID.
self.backgroundTaskID = UIApplication.shared.
beginBackgroundTask (withName: "Finish Network Tasks") {
// End the task if time expires.
UIApplication.shared.endBackgroundTask(self.backgroundTaskID!)
self.backgroundTaskID = UIBackgroundTaskInvalid
}
// Send the data synchronously.
self.sendAppDataToServer( data: data)
// End the task assertion.
UIApplication.shared.endBackgroundTask(self.backgroundTaskID!)
self.backgroundTaskID = UIBackgroundTaskInvalid
}
}
Edit
I didn't compile this code but based on the Apple documentation it could be done something like this:
final class ViewControler: UIViewController {
private var backgroundTaskID: UIBackgroundTaskIdentifier?
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 13.0, *) {
NotificationCenter.default.addObserver(self,
selector: #selector(willResignActive),
name: UIScene.willDeactivateNotification,
object: nil)
} else {
NotificationCenter.default.addObserver(self,
selector: #selector(willResignActive),
name: UIApplication.willResignActiveNotification,
object: nil)
}
}
@objc func willResignActive(_ notification: Notification) {
// Perform the task on a background queue.
DispatchQueue.global().async {
// Request the task assertion and save the ID.
self.backgroundTaskID = UIApplication.shared.beginBackgroundTask(withName: "Finish Network Tasks") {
// End the task if time expires.
UIApplication.shared.endBackgroundTask(self.backgroundTaskID!)
self.backgroundTaskID = .invalid
}
self.sendRequest()
}
}
func sendRequest() {
let URL: String = "http://www.test.com/"
AF.request(URL, method: .post, parameters: parameters, headers: headers)
.responseJSON { [unowned self] response in
// End the task assertion.
UIApplication.shared.endBackgroundTask(self.backgroundTaskID!)
self.backgroundTaskID = .invalid
switch response.result {
case .success(let data):
print(data)
case .failure(let error):
print(error)
}
}
}
}
In this code, we subscribe to the notification when the app will enter to the background and create a background task. In the background task, we perform a necessary request. If this request executes faster than 5 seconds in the response closure we invalidate our background task and finish work with it. If a request executes longer than 5 seconds then the background task terminates.