在下一个 UI 视图出现之前获取用户身份验证

Get user authentication before next UI View will appear

我正在处理用户身份验证过程,但我卡在了使用令牌从静止数据中恢复数据的那一刻。每当我创建新任务时,它不会在第一次进入该函数时进入该函数,但在创建它后会跳过执行其他操作,这会显示下一个连接 UIViewController 以继续。

我的休息服务使用 post 方法散列用户密码,创建 json、URL 请求并在最后创建 URLSession。我怎么能等到这个任务完成呢?在没有完成之前不让做任何其他事情?

编辑

我添加了 OpeartionQueue 以从下一个视图中清算 nil。

func postLogin(name:String, pass:String, completion: @escaping (Bool) -> () ) {
            let md5Data = self.MD5(string:pass)
            let hashPass = md5Data!.map { String(format: "%02hhx", [=11=]) }.joined()
            let json: [String: Any] = ["username": name,
                                       "passwordHash": hashPass ]

            let jsonData = try? JSONSerialization.data(withJSONObject: json)

            // create post request
            let url = URL(string: LOGIN_URL)!
            var request = URLRequest(url: url)
            request.httpMethod = "POST"

            // insert json data to the request
            request.httpBody = jsonData
            request.setValue("application/json;charest=utf-8", forHTTPHeaderField: "Content-Type")

            let task = URLSession.shared.dataTask(with: request) { data, response, error in
                guard let data = data, error == nil else {
                    print(error?.localizedDescription ?? "No data")
                    return
                }
                let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
                if let responseJSON = responseJSON as? [String: Any] {
                    print(responseJSON)
                    let message:String = responseJSON["message"] as! String
                    if !(message.range(of: "ERROR") != nil){
                        SessionMenager.Instance.token = message
                        completion(true)
                    }
                } else{
                    print(error.debugDescription)

                }
            }
        task.resume()
    }

然后只需在我的 LoginViewController 操作中使用按钮:

  @IBAction func LoginButton(_ sender: Any) {

   let username = usernameTextField.text
    let password = passwordTextField.text

    if username == "" {
        AlertWindow(title: "Username", message: "Wrong username")
    } else if password == "" {
        AlertWindow(title: "Password", message: "Wrong password")
    } else {
        let usernameToUpper = username!.uppercased()
        RestService.Instance.postLogin(name: usernameToUpper, pass: password!, completion: { sth in
            if sth {
                OperationQueue.main.addOperation {
                    [weak self] in
                    self?.performSegue(withIdentifier: "mapSegue", sender: self)
                }
            } else {
                return
            }
        })
    }
}

segue 连接到 LoginButton,这让我立即进入下一页。我已将其更改为连接所有视图控制器。

谢谢!

因为您的 segue 连接到 LoginButton,一旦您按下按钮,它会自动显示下一个 viewController。 只需将 segue 连接到整个 viewController 就可以了。