在确认我从 Udacity API 获得会话 ID 后,我正在尝试过渡到一个新的 segue。但是,在此之后我无法运行任何代码。会话 ID 和所有信息将打印出来,但之后什么都不会完成。我在函数中做错了什么吗?我尝试执行 UIUpdates,然后尝试打印“Hello”,但这也没有用。下面是一些代码和我的 GitHub 个人资料。 https://github.com/SteveBurgos95/UdacityMapProject
@IBAction func loginButton(_ sender: Any) {
UdacityClient.sharedInstance().loginWithUsername(emailTextField.text!, password: passwordTextField.text!){ (success, error) in
performUIUpdatesOnMain {
if success {
print("Hello")
} else {
print("Hey")
}
}
}
private func completeLogin() {
emailTextField.text = ""
let controller = storyboard!.instantiateViewController(withIdentifier: "TableMapViewController") as! UINavigationController
present(controller, animated: true, completion: nil)
在我看来,你永远不会在UdacityClient.swift
dataTask 完成时调用你的完成处理程序(无论是在错误还是成功的情况下)?
这应该是这样的:
let task = session.dataTask(with: request as URLRequest) { data, response, error in
// Make sure there is no error, or else
guard error == nil else { // Handle error…
completionHandler(false, error?.localizedDescription)
/*
func sendError(_ error: String) {
print(error)
let userInfo = [NSLocalizedDescriptionKey : error]
completionHandlerForGET(nil, NSError(domain: "taskForGETMethod", code: 1, userInfo: userInfo))
*/
return
}
completionHandler(true, nil)
}
查看代码后,UI 未更新,因为您尚未sucess
在UdacityClient.swift
. 块sucess
/关闭escapes
。所以你不会收到回调
UdacityClient.sharedInstance().loginWithUsername(emailTextField.text!, password: passwordTextField.text!){
像下面这样更改功能
func loginWithUsername(_ username: String, password: String, completionHandler: @escaping (_ success: Bool, _ errorMessage: String?) -> Void ) {
let request = NSMutableURLRequest(url: URL(string: "https://www.udacity.com/api/session")!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = "{\"udacity\": {\"username\": \"\(username)\", \"password\": \"\(password)\"}}".data(using: String.Encoding.utf8)
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) { data, response, error in
if error != nil
// Handle error…
/*
func sendError(_ error: String) {
print(error)
let userInfo = [NSLocalizedDescriptionKey : error]
completionHandlerForGET(nil, NSError(domain: "taskForGETMethod", code: 1, userInfo: userInfo))
*/
return
}
completionHandler(true,nil)
let range = Range(5..<data!.count)
let newData = data?.subdata(in: range) /* subset response data! */
print(NSString(data: newData!, encoding: String.Encoding.utf8.rawValue)!)
}
task.resume()
}
在 performUIUpdatesOnMain 关闭之前打印时,您是否看到任何内容?
@peter 是的,我会打印出与此类似的内容。这是 API 的预期行为。{ “帐户”:{ “注册”:true, “密钥”:“3903878747” }, “会话”:{ “id”:“1457628510Sc18f2ad4cd3fb317fb8e028488694088”, “到期”:“2015-05-10T16:48:30.760460Z” } }
此解决方案中的 if 语句是从原始代码段反转过来的,条件是 now error == nilinstead of error != nilwhich 使闭包的其余部分变得毫无意义。此外,这仅在登录成功的情况下有效,并且在登录失败时会出现相同的错误。请检查我的解决方案以获得更完整的解决方案:stackoverflow.com/a/45026732/1415898