#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() }