验证来自API的数据后尝试segue时出现身份验证错误/紫色警告



我已经创建了一个POST请求,验证用户名和密码是否正确,通过来自POST请求的响应的StatusCode: 0,如果数据是正确的,在signInViewController类我已经创建了按钮signInSegueToDashboard,按下必须验证数据,如果数据是有效的,那么用户将登录没有任何问题。

signInViewController的按钮发送者:

@IBAction func signInSegueToDashboard(_ sender: Any) {

APICallerPOST.shared.signInToAccount(username: emailTextField.text!, password: passwordTextField.text!) { (result, error) in
if let result = result {

if result.StatusCode == 0 {

guard let mainTabBarController = self.storyboard?.instantiateViewController(withIdentifier: "mainTabBarController") else {
return
}

Timer.scheduledTimer(withTimeInterval: 1, repeats: false) {_ in

mainTabBarController.modalPresentationStyle = .custom
self.present(mainTabBarController, animated: true, completion: nil)
}

}else if result.StatusCode == 5 {
print("error: (error!.localizedDescription)")
}
}
}
}

当我在输入正确的数据后按下按钮,它只是什么也不做,只是显示一个紫色的警告,说把它放在主线程,当我把segue部分放在主线程,然后它根本不验证数据,而是只是登录你没有任何验证。

APICallerPOST类的POST请求:

func signInToAccount(username: String, password: String, completion: @escaping (SignInResponse?, Error?) -> Void) {

//declare parameter as a dictionary which contains string as key and value combination.
let parameters = ["User": username, "Password": password]

//create the url with NSURL
let url = URL(string: "https://censoredurl/Signin")!

//create the session object
let session = URLSession.shared

//now create the Request object using the url object
var request = URLRequest(url: url)
request.httpMethod = "POST" //set http method as POST

do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) // pass dictionary to data object and set it as request body
} catch let error {
print(error.localizedDescription)
completion(nil, error)
}

//HTTP Headers
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")

//create dataTask using the session object to send data to the server
let task = session.dataTask(with: request, completionHandler: { data, response, error in

guard error == nil else {
completion(nil, error)
return
}

guard let data = data else {
completion(nil, NSError(domain: "dataNilError", code: -100001, userInfo: nil))
return
}

do {
//create json object from data
let decoder = JSONDecoder()

guard let json = try? decoder.decode(SignInResponse.self, from: data) else {
completion(nil, NSError(domain: "invalidJSONTypeError", code: -100009, userInfo: nil))
return
}

print(json)
completion(json, nil)

} catch let error {
print(error.localizedDescription)
completion(nil, error)
}
})

task.resume()
}

很困惑。

dataTask是异步的,它在完成处理程序中运行的代码也是异步的。然而,所有的UI更新都需要在主线程上执行,所以完成处理程序中更新UI的部分需要被推回主线程。

你可以这样做:

if result.StatusCode == 0 {
DispatchQueue.main.async {
guard let mainTabBarController = self.storyboard?.instantiateViewController(withIdentifier: "mainTabBarController") 
else { 
return
}
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) {_ in
mainTabBarController.modalPresentationStyle = .custom
self.present(mainTabBarController, animated: true, completion: nil)
}
}
// ...

然而,似乎你正试图使用定时器来延迟viewController的呈现,并且有比使用定时器更好的方法来做到这一点。您可以使用DispatchQueue的asyncAfter(deadline:qos:flags:execute:)方法来延迟执行:

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
// do your UI work
}

最新更新