Не удается получить доступ к данным JSON из API погоды - PullRequest
0 голосов
/ 27 апреля 2020
class WeatherData {
    private let urlSession = URLSession.shared
    private let urlPathBase = "https://api.worldweatheronline.com/premium/v1/weather.ashx?key=efcc8b6300354517b08194421202604&format=json&q="

    private var dataTask:URLSessionDataTask? = nil

    var delegate:WeatherDataProtocol? = nil

    init(){}

    func getData(exampleDataNumber: String){

        var urlPath = self.urlPathBase
        urlPath = urlPath + exampleDataNumber

        let url:NSURL? = NSURL(string: urlPath)
        print(url!)

        let dataTask = self.urlSession.dataTask(with: url! as URL) {(data, response, error) -> Void in
            if error != nil {
                print(error!)
            } else {
                do {
                    let jsonResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
                    if jsonResult != nil {
                        print(jsonResult)
                        let temperature_c = jsonResult?.value(forKeyPath: "data.current_condition.temp_C") as Any

                        if temperature_c != nil {
                            self.delegate?.responseDataHandler(data: jsonResult!)
                        } else {
                            self.delegate?.responseError(message: "Fake data not found")
                        }
                    } else {
                        print("Fake data")
                    }
                } catch {
                    print("Error")
                }
            }
        }

    }





}

У меня есть вышеуказанный код для доступа к worldweatheronline API. В контроллере представления я беру значение, которое пользователь вводит в поле города и штата, и передаю его в getData как exampleDataNumber с запятой между ними и пробелами, удаленными с помощью + (например, Остин, Техас или Сан + Франциско, Калифорния). Это основано на коде, который мой профессор дал нам для отдельного примера, который работал, но по какой-то причине с этим кодом все, что он сделает, это напечатает URL, но все другие операторы печати, которые я вставил, чтобы попытаться увидеть данные, которые проходят через все, не печатают ничего, что действительно смущает меня, потому что кажется, что что-то должно печатать. Я знаю, что API отвечает HTTP вместо HTTPS, но я добавил в настройках безопасности транспорта приложения мой Info.plist, чтобы разрешить insecureHTTPLoads (пробовал worldweatheronline. net и worldweatheronline.com). Есть ли что-то еще, что мне не хватает? enter image description here

Ответы [ 2 ]

1 голос
/ 27 апреля 2020

Код в порядке, я думаю, вы просто пропустили вызов метода resume для задачи с данными. Также, как вы сказали, исключение ATS не требуется, поскольку API использует https. Когда вы определяете let datatask = ... в конце, просто добавьте .resume(), чтобы сразу запустить задачу.

Примерно так:

  class WeatherData {
     private let urlSession = URLSession.shared
     private let urlPathBase = "https://api.worldweatheronline.com/premium/v1/weather.ashx?key=efcc8b6300354517b08194421202604&format=json&q="

     private var dataTask:URLSessionDataTask? = nil

     var delegate:WeatherDataProtocol? = nil

     init() {
     }

     func getData(exampleDataNumber: String){

        var urlPath = self.urlPathBase
        urlPath = urlPath + exampleDataNumber

        let url:NSURL? = NSURL(string: urlPath)
        print(url!)

        let dataTask = self.urlSession.dataTask(with: url! as URL) {(data, response, error) -> Void in
           if error != nil {
              print(error!)
           } else {
              do {
                 let jsonResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
                 if jsonResult != nil {
                    print(jsonResult)
                    let temperature_c = jsonResult?.value(forKeyPath: "data.current_condition.temp_C") as Any

                    if temperature_c != nil {
                       self.delegate?.responseDataHandler(data: jsonResult!)
                    } else {
                       self.delegate?.responseError(message: "Fake data not found")
                    }
                 } else {
                    print("Fake data")
                 }
              } catch {
                 print("Error")
              }
           }
        }.resume()
     }
  }

Я создал крошечный проект для его проверки и выглядит хорошо :

Request valid data number

Request blank data number

Если вы хотите поиграть с примером проекта, вы можете скачать его from: https://github.com/acyrman/StackOverflow61449278

Мне пришлось создать и реализовать WeatherDataProtocol, так как вы не поделились этим кодом, я создаю очень простой для компиляции проекта.

0 голосов
/ 27 апреля 2020

Удалите let из объявления dataTask в вашей функции. Вам нужно установить ivar, чтобы он имел надежную ссылку, пока выполняется URLSession.

...