【问题标题】:How do I set a the serverResponse var from within the if let data string statement如何从 if let data string 语句中设置 serverResponse var
【发布时间】:2020-05-06 04:10:22
【问题描述】:
func getResponse(serverName: String) -> String {

        var serverResponse: String = "No Response"
        let serverURL = "http://" + serverName + ":3000"

        if let url = URL(string: serverURL) {
           URLSession.shared.dataTask(with: url) { data, response, error in
              if let data = data {
                if let jsonString = String(data: data, encoding: .utf8) {

                    serverResponse = jsonString
                    print(jsonString)
                 }
               }
           }.resume()
        }
    return serverResponse
}

我正在尝试从 if let jsonString 中设置 serverResponse 变量,但它始终返回“No response”(vars 默认值),并且 if let jsonString 中的 print 函数将打印出服务器响应。

【问题讨论】:

  • dataTask 是异步的。您的函数在服务器请求完成之前返回值。

标签: swift var


【解决方案1】:

DataTask 是异步的。您的函数在服务器请求完成之前返回该值。您应该在这里使用完成处理程序。

func getResponse(serverName: String , completion : @escaping (Bool,String?) -> ()) {

        let serverURL = "http://" + serverName + ":3000"
        if let url = URL(string: serverURL) {
           URLSession.shared.dataTask(with: url) { data, response, error in
              if let data = data {
                if let jsonString = String(data: data, encoding: .utf8) {
                    print(jsonString)
                    completion(true,jsonString)
                 }
              } else {
                completion(false,nil)
            }
           }.resume()
        }
}

那么就可以这样调用上面的函数了:

    getResponse(serverName: "yourServerName") { (isSuccess, response) in
        if isSuccess {
            self.serverResponse = response ?? ""
        } else {
            // your api request failed. show alert or whatever you want to inform the user.
        }
    }

【讨论】:

    【解决方案2】:

    您需要添加completionHandler

    func getResponse(serverName: String, onCompletion: @escaping (String?) -> Void) {
    
        var serverResponse: String = "No Response"
        let serverURL = "http://" + serverName + ":3000"
    
        if let url = URL(string: serverURL) {
           URLSession.shared.dataTask(with: url) { data, response, error in
              if let data = data {
                if let jsonString = String(data: data, encoding: .utf8) {
    
                    serverResponse = jsonString
                    print(jsonString)
    
                    onCompletion(serverResponse)
                 }
               }
           }.resume()
     }
    }
    

    【讨论】:

      【解决方案3】:

      getResponse(serverName:)方法外创建serverResponse,并使用属性观察者 didSet观察serverResponse的变化,即

      var serverResponse: String = "No Response" {
          didSet {
              print("newValue: ", serverResponse)
              //add the code here..
          }
      }
      

      didSet 将在每次serverResponse 有任何变化时被调用。所以,在从 API 获取 serverResponse 后要运行的任何代码,都写在这里。

      另外,不需要从getResponse(serverName:) 方法返回任何东西。因此,该方法现在看起来像,

      func getResponse(serverName: String) {
          let serverURL = "http://" + serverName + ":3000"
          if let url = URL(string: serverURL) {
              URLSession.shared.dataTask(with: url) { data, response, error in
                  if let data = data {
                      if let jsonString = String(data: data, encoding: .utf8) {
                          serverResponse = jsonString
                          print(jsonString)
                      }
                  }
              }.resume()
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-05-12
        • 2017-05-29
        • 1970-01-01
        • 1970-01-01
        • 2018-09-16
        • 1970-01-01
        • 2021-03-27
        • 2014-03-29
        • 2016-08-15
        相关资源
        最近更新 更多