Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Swift Only run on the main thread error for app

I am new to swift and I have a login page that takes the users credentials and check if it's the right credentials . I think return the response in JSON if it's the right credentials then I try to go to a new ViewController .I got this error when I try to go to a new View Controller, I have this in a closure so I do not know why I am getting this issue. This is my code

func LoginClosure(completion:@escaping (Bool) ->Void) {
    var check = 0
    let url:URL = URL(string:ConnectionString+"login")!

    if submitEmail == nil || submitPassword == nil {
        submitEmail = email.text!
        submitPassword = password.text!
    }

    let session = URLSession.shared
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    let parameter = "Email=\(submitEmail!)&password=\(submitPassword!)"
    request.httpBody = parameter.data(using: String.Encoding.utf8)
    DispatchQueue.main.async {
        session.dataTask(with:request, completionHandler: { (data, response, error) in
            if error != nil {
                // print(error)
            } else {
                do {
                    let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:Any]

                    if let Streams = parsedData?["Profile"] as? [AnyObject]  {
                        // check for misspelled words
                        for Stream in Streams {
                            if let rr = Stream["result"] as? Bool {
                                self.result = rr
                            } else {
                                self.result = true
                            }

                            if let id = Stream["id"] as? Int {
                                self.defaults.setValue(id, forKey: "my_id")
                                // Success
                                MYID = id
                                completion(true)
                                return
                            }
                        }

                        if check == 0 {
                            // Bad credentials
                            completion(false)
                        }
                    }
                } catch let error as NSError {
                    print(error)
                }
            }
        }).resume()
    }
}

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only run on the main thread!'

That error occurs with this line:

let next = self.storyboard?.instantiateViewController(withIdentifier: "AccountC") as! AccountC
self.present(next, animated: true, completion: nil)
like image 711
user1591668 Avatar asked Dec 13 '22 16:12

user1591668


2 Answers

As per apple standards, you have to perform UI activity in the main queue only.

Just call your closure in the main queue as below.

DispatchQueue.main.async {
    completion(true)
}

You can also perform only UI changes in the main queue as below.

DispatchQueue.main.async {
    let next = self.storyboard?.instantiateViewController(withIdentifier: "AccountC") as! AccountC
    self.present(next, animated: true, completion: nil)
}

@rmaddy Thanks for the valuable suggestion.

like image 158
Hitesh Surani Avatar answered Jan 07 '23 18:01

Hitesh Surani


In your code, I see that you have initiated the network call in the main queue. That makes sure that creation of the data task and starting it off will be performed on the main thread. But it doesn't guarantee that the completion closure will also be called on the main thread.

Therefore I would suggest removing the network call from the DispatchQueue.main.async block. Then please execute the code that performs UI updation in a DispatchQueue.main.async block as follows.

DispatchQueue.main.async {    
    let next = self.storyboard?.instantiateViewController(withIdentifier: "AccountC") as! AccountC
    self.present(next, animated: true, completion: nil)
}
like image 32
humblePilgrim Avatar answered Jan 07 '23 20:01

humblePilgrim