Home > OS >  Alamofire request in app moved to background. Connection lost
Alamofire request in app moved to background. Connection lost

Time:10-21

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.

  • Related