-1

I have given DispatchQueue.main.async {} where it necessary but when i give break point from dataTask here it says

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.'

Cannot be called with asCopy = NO on non-main thread.

  class EventsViewController: UIViewController {

@IBOutlet weak var backBtn: UIButton!
var eventsListArray = [AnyObject]()
var eventType: String?
var eventList : EventsModel? = nil

@IBOutlet weak var eventsTableView: UITableView!
    
override func viewDidLoad() {
    super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
   
    getAllEventsList()
}


func getAllEventsList() {
    DispatchQueue.main.async {

    let deviceId: String = (UIDevice.current.identifierForVendor?.uuidString)!

    let personalId: String = UserDefaults.standard.string(forKey: "regUserID") ?? ""//KeychainWrapper.standard.string(forKey: "USERID") ?? ""
   
    let headers = ["deviceid": deviceId,"userType": "personal","key": personalId]
        DispatchQueue.main.async {

    let string = Constants.GLOBAL_URL + "/get/allevents"
    var urlComponents = URLComponents(string: string)
    
    let eventStatus = self.eventType
    let requestEventType = URLQueryItem(name: "eventstatus", value: eventStatus)

    urlComponents?.queryItems = [requestEventType]
    let urlStr = urlComponents?.url
    
    let request = NSMutableURLRequest(url: urlStr!, cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers as! [String : String]
    let session = URLSession.shared

    let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
        if error == nil {

            let httpResponse = response as? HTTPURLResponse
            if httpResponse!.statusCode == 200 {
                do {
                    let jsonObject  = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! [String :AnyObject]
                    print("publish event \(jsonObject)")
                    
                    self.eventList = EventsModel.init(fromDictionary: jsonObject)
                    
                    DispatchQueue.main.async {

                    if self.eventList?.events.count != 0 {
                        DispatchQueue.main.async {
                            self.eventsTableView.reloadData()
                        }
                    }
                    
                    else {
                        
                        DispatchQueue.main.async {
                            Constants.showAlertView(alertViewTitle: "", Message: "No Events \(self.eventType)", on: self)
                            self.eventList?.events.removeAll()
                            self.eventsTableView.reloadData()
                        }
                    }
                    
                }
                } catch { print(error.localizedDescription) }
            } else {
                Constants.showAlertView(alertViewTitle: "", Message: "Something went wrong, Please try again", on: self)
            }
    }
    })
        
    dataTask.resume()
        }
}
}
}
Swift
  • 1,074
  • 12
  • 46

1 Answers1

1

You've probably missed a few spots where you're trying to present an alert when errors are thrown. Why don't you just enter the main queue right after the data request is complete.

let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
    DispatchQueue.main.async {
        if error == nil {
        //...
        }
    }
})
Frankenstein
  • 15,732
  • 4
  • 22
  • 47
  • if there is a chance.. please answer here https://stackoverflow.com/questions/63439649/unable-to-add-parameter-to-api-in-swift – Swift Aug 16 '20 at 17:09