Как установить переменную serverResponse из оператора if let строки данных - PullRequest
0 голосов
/ 20 января 2020
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
}

Я пытаюсь установить переменную serverResponse изнутри if let jsonString, но она всегда возвращает «No response» (vars default), а функция печати изнутри if let jsonString выведет ответ сервера.

Ответы [ 3 ]

1 голос
/ 20 января 2020

Вам необходимо добавить 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()
 }
}
1 голос
/ 20 января 2020

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.
        }
    }
0 голосов
/ 20 января 2020

Создайте serverResponse вне метода getResponse(serverName:) и используйте наблюдатель свойства didSet, чтобы наблюдать изменения в serverResponse, т.е.

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

didSet будет вызываться каждый раз, когда происходит изменение serverResponse. Итак, любой код, который вы хотите запустить после получения serverResponse от API, напишите здесь.

Кроме того, нет необходимости возвращать что-либо из метода 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()
    }
}
...