Swift:在收到API响应之前保持代码执行

Swift:在收到API响应之前保持代码执行,swift,api,concurrency,closures,Swift,Api,Concurrency,Closures,我需要设置授权屏幕: 1) 输入登录和通行证 2) 应用程序从API请求令牌 3) 收到答复 4) 应用程序检查响应是否包含令牌:如果包含,则应执行授权 需要解决的问题:应用程序在第3步之前完成4) 我尝试的内容:我使用转义闭包来保持执行直到收到API数据,但它只起到了部分作用——它只帮助保持对令牌的赋值,但我不能保持“if checks” override func shouldPerformSegue(withIdentifier identifier: String, sender

我需要设置授权屏幕:

1) 输入登录和通行证

2) 应用程序从API请求令牌

3) 收到答复

4) 应用程序检查响应是否包含令牌:如果包含,则应执行授权

需要解决的问题:应用程序在第3步之前完成4)

我尝试的内容:我使用转义闭包来保持执行直到收到API数据,但它只起到了部分作用——它只帮助保持对令牌的赋值,但我不能保持“if checks”

    override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    if identifier == "loginSegue" {

        let login = loginInput.text!
        let password = passInput.text!

        tokenLoader.getToken(login: login, password: password) { [weak self] token in
            self?.token = token.access_token
        }

        //THIS CODE I NEED TO HOLD UNTIL DATA FROM API RECEIVED
        if token != "" {
            return true
        } else {
            let alert = UIAlertController(title: nil, message: "Incorrect password", preferredStyle: .alert)
            let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
            alert.addAction(action)
            present(alert, animated: true, completion: nil)
            return false
        }
        //

    } else {
        return true
    }
}

您可以使用此功能解决此问题。。。当您想要继续或获取令牌时,在事件上执行它

func getTokenAndPerformSegue() {
    let login = loginInput.text
    let password = passInput.text

    if let getLogin = login ,let getPassword = password {

    tokenLoader.getToken(login: getLogin, password: getPassword) { [weak self] token in
           self?.token = token.access_token

        if token.isEmpty() {
            let alert = UIAlertController(title: nil, message: "Incorrect password", preferredStyle: .alert)
            let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
            alert.addAction(action)
            present(alert, animated: true, completion: nil)
        } else {
             performSegue(withIdentifier: "loginSegue", sender: nil)
        }

       }
    }

}
你需要这样写。。。返回零或完成时出错

 func getToken(login: String, password: String, completion: @escaping (AccessToken?) -> Void) {
        let path = "/token"
        let parameters: Parameters = [
            "grant_type": "client_credentials",
            "client_id": login,
            "client_secret": password,
            "scope": "read"
        ]
        let url = baseUrl+path
        AF.request(url, method: .get, parameters: parameters).responseData { response in

            do {
                let token = try JSONDecoder().decode(AccessToken.self, from: response.value!)
                print(token)
                self.session.token = token.access_token
                completion(token)

            } catch {
                completion(nil)
                print(error)
            }
        }
    }

如果您没有得到任何帮助或需要进一步帮助,请告诉我您可以使用此功能解决此问题。。。当您想要继续或获取令牌时,在事件上执行它

func getTokenAndPerformSegue() {
    let login = loginInput.text
    let password = passInput.text

    if let getLogin = login ,let getPassword = password {

    tokenLoader.getToken(login: getLogin, password: getPassword) { [weak self] token in
           self?.token = token.access_token

        if token.isEmpty() {
            let alert = UIAlertController(title: nil, message: "Incorrect password", preferredStyle: .alert)
            let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
            alert.addAction(action)
            present(alert, animated: true, completion: nil)
        } else {
             performSegue(withIdentifier: "loginSegue", sender: nil)
        }

       }
    }

}
你需要这样写。。。返回零或完成时出错

 func getToken(login: String, password: String, completion: @escaping (AccessToken?) -> Void) {
        let path = "/token"
        let parameters: Parameters = [
            "grant_type": "client_credentials",
            "client_id": login,
            "client_secret": password,
            "scope": "read"
        ]
        let url = baseUrl+path
        AF.request(url, method: .get, parameters: parameters).responseData { response in

            do {
                let token = try JSONDecoder().decode(AccessToken.self, from: response.value!)
                print(token)
                self.session.token = token.access_token
                completion(token)

            } catch {
                completion(nil)
                print(error)
            }
        }
    }

如果您没有得到任何帮助或需要进一步帮助,请告诉我

shouldPerformSegue
不是用于异步任务的函数。将代码放在其他地方(可能是第二个ViewController的ViewLoad)。将令牌调用后要执行的任何操作移动到闭包中(设置令牌的位置)触发
shouldPerformSegue(带标识符:sender:)
?ie何时调用该序列的
performsgue(带标识符:sender)
?一旦您获得令牌,就让它调用它。
shouldPerformSegue
不是一个可用于异步任务的函数。将代码放在其他地方(可能是第二个ViewController的ViewLoad)。将令牌调用后要执行的任何操作移动到闭包中(设置令牌的位置)触发
shouldPerformSegue(带标识符:sender:)
?ie何时调用该序列的
performsgue(带标识符:sender)
?收到代币后立即拨打。非常感谢您的回复!我将shouldPerformSegue改为func(根据上面的例子),现在系统保存代码直到收到API请求!但有一个bug仍然存在:若API响应为nil(密码不正确),则不会执行token.isEmpty()部分。如何获得nil?在当前实现中的哪个变量响应中,您只是在Catch中的func getToken中获得tokenI receive error。问题中此方法的代码。非常感谢您的回复!我将shouldPerformSegue改为func(根据上面的例子),现在系统保存代码直到收到API请求!但有一个bug仍然存在:若API响应为nil(密码不正确),则不会执行token.isEmpty()部分。如何获得nil?在当前实现中的哪个变量响应中,您只是在Catch中的func getToken中获得tokenI receive error。问题中此方法的代码。