我已经创建了一个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
}