如何使用数组对 API 数据进行 Json 解码?

Posted

技术标签:

【中文标题】如何使用数组对 API 数据进行 Json 解码?【英文标题】:How to Json decode API data with an array? 【发布时间】:2022-01-13 12:52:48 【问题描述】:

我正在学习 Swift 并尝试根据来自 Open Elevation 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()
  

【讨论】:

以上是关于如何使用数组对 API 数据进行 Json 解码?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AlamoFire 搜索 JSON API 和解码数组

使用swift解码巨大的JSON数组URL

将图像数组转换为 JSON 文件并在 C# 之后对其进行解码

PHP-解码 JSON

如何将json数据解码为objective-c中的数组[重复]

如何从其他站点检索 json 数据并使用 cURL 对其进行解码?