【问题标题】:How to return a value from a closure back to a function in Swift?如何将闭包中的值返回给Swift中的函数?
【发布时间】:2021-05-04 16:06:08
【问题描述】:

我的问题是 Request 函数的值仅在第二次通过后才返回。 我尝试了@escaping 和 Dispatch,但该值仍然只在第二遍之后才回来。 这些函数的要点是你需要把“Login”和“Password”这两个字段发送到服务器,然后得到一个JSON格式的响应并解包,然后在应用程序中登录或不登录 代码如下:

// request function
func request(url: String, login: String, password: String, completion: @escaping (String)->()){
        
        guard let connectionUrl = URL(string: url) else { return }
        let parameters = ["username": login, "password": password]
        var request = URLRequest(url: connectionUrl)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else
        { return }
        
        request.httpBody = httpBody
        let session = URLSession.shared
        session.dataTask(with: request) { (data, response, _) in
            if let response = response  { print(response) }
            guard let data = data else { return }
            let result =  self.parse(json: data)
            DispatchQueue.main.async{
                completion(result)
            }
           
        }.resume()
      //  return result
    }

// Button handler 
@IBAction func loginButtonPressed(_ sender: UIButton) {
        guard let login = loginTextField.text, let password = passwordTextField.text else {return}
        server.request(url: urlString, login: login, password: password) {
             result in
//It goes here even on the first pass and assigns everything correctly.
                if result == "s kaifom" {
                    self.server.answerFromServer = true
                } else {
                    self.server.answerFromServer = false
                }
//After passing the last curly bracket the value is reset and then falls into the "else" block
        }

//  This "if" is skipped on the first pass and falls right into the "else" block

        if self.server.answerFromServer && !login.isEmpty && !password.isEmpty{
            let storyboard = UIStoryboard(name: "Main", bundle: nil);
            let vc = storyboard.instantiateViewController(withIdentifier: "GuestScreen") as! GuestViewController;
            self.present(vc, animated: true, completion: nil);
        }
        else{
            sender.shake()
        }
    }

【问题讨论】:

  • "//通过最后一个大括号后,值被重置,然后落入“else”块“不,不是这样。它不是“重置”。在大括号之前添加打印,例如 print("Inside closure") 和之后:print("outside closure") 先打印哪个?您希望首先在控制台中看到哪个?你不想返回,你想做 if/else ONCE 你得到result 回调。
  • 既然您的 cmets 说“一切都正确分配”,这意味着您得到了服务器的响应,对吗?那么结果 == "s kaifom" 是真是假呢?
  • "s kaifom" 是真的
  • 第一个是“外封”,第二个是“内封”。
  • 而当您再次按下按钮时(对于该功能的第二次传递),打印件也首先显示在 clogger 外部,然后在其中显示。但是,在这种情况下,该功能可以正常工作。 @Larme

标签: ios swift function closures


【解决方案1】:

解决方案非常简单,只需将所有代码推入闭包即可。

server.request(url: urlString, login: login, password: password) {
             result in
                if result == "s kaifom" {
                    self.server.answerFromServer = true
                } else {
                    self.server.answerFromServer = false
                }
            print("inside closure")
            if self.server.answerFromServer && !login.isEmpty && !password.isEmpty{
                let storyboard = UIStoryboard(name: "Main", bundle: nil);
                let vc = storyboard.instantiateViewController(withIdentifier: "GuestScreen") as! GuestViewController;
                self.present(vc, animated: true, completion: nil);
            }
            else{
                sender.shake()
            }
        }

【讨论】:

    猜你喜欢
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多