Search code examples
iosswiftxcodensurlsession

Error in background/main thread using API


I try to call my API, but I get an error:

Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.

I understand that I need to call DispatchQueue, but I don't understand where I need use it.

My code:

let currentUser = Auth.auth().currentUser
currentUser?.getIDTokenForcingRefresh(true, completion: { (idToken, error) in
    if let err = error {
        self.unknownError(error: err)
    } else {
        var request = URLRequest(url: URL(string: "https://phss.ru/api/booking/cancel")!)
        request.httpMethod = "POST"
        let cancelBooking: [String: Any] = ["booking_id": self.documentIDs]
        let jsonData = try! JSONSerialization.data(withJSONObject: cancelBooking, options: [])
        request.httpBody = jsonData
        request.addValue("Bearer \(idToken!)", forHTTPHeaderField: "Authorization")
        let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
            if let err = error {
                self.unknownError(error: err)
            } else {
                let alertController = UIAlertController(title: NSLocalizedString("Cancel successful", comment: "Cancel successful"), message: "", preferredStyle: .alert) 
                alertController.addAction(UIAlertAction(title: NSLocalizableOk, style: .cancel, handler: nil))
                self.present(alertController, animated: true, completion: nil)
            }
        })
    task.resume()
    }
})

Solution

  • You need to present your UIAlertController on the main thread because the completion callback of URLSession.shared.dataTask(with:completionHandler:) runs on a background thread.

    DispatchQueue.main.async {
       let alertController = UIAlertController(title: NSLocalizedString("Cancel successful", comment: "Cancel successful"), message: "", preferredStyle: .alert) 
       alertController.addAction(UIAlertAction(title: NSLocalizableOk, style: .cancel, handler: nil))
       self.present(alertController, animated: true, completion: nil)
    }