Как Json декодировать данные API с помощью массива?

#arrays #swift #xcode #urlsession #jsondecoder

#массивы #быстрый #xcode #сеанс URL-адресов #jsondecoder

Вопрос:

Я изучаю Swift и пытаюсь получить данные о высоте на основе координат из открытого API высот.

Я нашел код для выполнения запроса и декодирования данных с помощью структур.

Моя проблема в том, что результат API включает информацию в массив:

 {"results": [{"latitude": 41.161758, "longitude": -8.583933, "elevation": 117}]}  

То, что я смог запрограммировать до сих пор, сохраняет данные в виде массива в json.results, но только с одним индексом, включающим все данные:

 [API.MyResult(latitude: 41.16176, longitude: -8.583933, elevation: 117)]  

(«API» — это имя файла)

Вот мой код:

 import UIKit  class ViewController: UIViewController {     override func viewDidLoad() {  super.viewDidLoad()  // Do any additional setup after loading the view.      let url = "https://api.open-elevation.com/api/v1/lookup?locations=41.161758,-8.583933"    getData(from: url)    }         private func getData(from url: String){    let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: {data, response, error in    guard let data = data, error == nil else {  print("error")  return  }    var result: Response?  //print(result)        do{  result = try JSONDecoder().decode(Response.self, from: data)  }  catch{  print(error.localizedDescription)  }      guard let json = result else {  return  }        print(json.results)    //print(json.results.latitude)  //print(json.results.longitude)  //print(json.results.elevation)      })  task.resume()  }       }      struct Response: Codable {  let results: [MyResult] }   struct MyResult: Codable {  let latitude: Float  let longitude: Float  let elevation: Int }  

Попытка распечатать файл json.results.latitude приводит к ошибке

 "Value of type '[MyResult]' has no member 'latitude'"  

Я предполагаю, что в какой-то момент переменная должна быть определена как массив.

Что здесь нужно изменить?

Ответ №1:

result действительно, это один объект, но свойство results представляет собой массив (несколько объектов).

Немного другое название позволяет избежать путаницы.

Примечания:

  • Никогда не печатайте буквальный "error" или error.localizedDescription в контексте декодирования, всегда печатайте error экземпляр.
  • Перейдите к анализу результата в do области
     private func getData(from url: String){  guard let url = URL(string: url) else { print("Bad URL", url); return }  let task = URLSession.shared.dataTask(with: url) {data, _, error in  if let error = error { print(error); return }  do {  let response = try JSONDecoder().decode(Response.self, from: data!)  for result in response.results {  print(result.latitude)  print(result.longitude)  print(result.elevation)  }  }  catch {  print(error)  }  }  task.resume()  }