IOS Swift只运行应用程序的主线程错误

时间:2018-05-09 05:09:36

标签: ios swift uistoryboard

我是swift的新手,我有一个登录页面,可以获取用户凭据并检查它是否是正确的凭据。我认为如果它是正确的凭据,我会在Json中返回响应,然后我尝试转到新的ViewController。当我尝试转到新的View Controller时出现此错误,我将其关闭,所以我做了不知道为什么我会遇到这个问题。这是我的代码

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()
    }
}
  

***由于未捕获的异常终止应用程序' NSInternalInconsistencyException',原因:'仅在主要运行   线程'!

此行发生错误:

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

2 个答案:

答案 0 :(得分:4)

  

根据Apple标准,您必须仅在主队列中执行UI活动。

只需在DispatchQueue.main.async { completion(true) } 中拨打您的关闭,如下所示。

main queue

更新:您还可以在 DispatchQueue.main.async { let next = self.storyboard?.instantiateViewController(withIdentifier: "AccountC") as! AccountC self.present(next, animated: true, completion: nil) } 中仅执行以下UI更改。

webstorm .

@rmaddy感谢宝贵的建议。

答案 1 :(得分:1)

在您的代码中,我看到您已在主队列中启动了网络呼叫。这确保了将在主线程上执行数据任务的创建并将其启动。但它并不能保证在主线程上也会调用完成闭包。

因此我建议从DispatchQueue.main.async块中删除网络呼叫。然后,请执行在DispatchQueue.main.async block中执行UI更新的代码,如下所示。

 DispatchQueue.main.async {


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