如何使用 Codable 提取 json 的结果

How to extract the result of json with Codable

我是第一次使用 Codable,想输出 Google Places 详细信息的 json 结果作为标签。 然而,当我打印它时,控制台显示“无法读取数据,因为它的格式不正确。”。 自己解决不了,请教我正确的写法

谢谢。

json

的结果
{
"html_attributions": [],
"result": {
"formatted_phone_number": "XXXX-XXX-XXX",
"website": "https://www.xxxxx.com/xxxxxx/"
},
"status": "OK"
}

Detail.swift

import Foundation


struct Details : Codable {
    var formatted_phone_number : String!
    var website : String!
}

ViewController.swift

override func viewDidLoad() {
        super.viewDidLoad()

fetchDetailData {(details) in
            for detail in  details{
                print(detail.website)
            }
            
        }
}

func fetchDetailData(completionHandler: @escaping ([Details]) -> Void){
        let url = URL(string: "https://maps.googleapis.com/maps/api/place/details/json?place_id=\(place_id)&fields=formatted_phone_number,website&key=\(apikey)")!
        let task = URLSession.shared.dataTask(with: url){
            (data,respose, error)in
            guard let data = data else{ return }
            do {
                let detailsData = try JSONDecoder().decode([Details].self, from: data)
                completionHandler(detailsData)
            }
            catch{
            let error = error
                print(error.localizedDescription)
                    }
            }.resume()
        }

其中一个问题是结果是字典而不是数组。您还需要解码根结构以从中提取结果。请注意,您还可以将网站类型从字符串更改为 URL:

struct Root: Codable {
    let htmlAttributions: [String]  // make sure to define the proper type in case the collection is not empty
    let result: Result
    let status: String
}

struct Result: Codable  {
    let formattedPhoneNumber: String
    let website: URL
}

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let result = try decoder.decode(Root.self, from: data).result
    print(result)
} catch { 
    print(error) 
}

这将打印

Result(formattedPhoneNumber: "XXXX-XXX-XXX", website: https://www.xxxxx.com/xxxxxx/)

你能试试这个吗;

struct Place {
let result: Details?
}

struct Details: Codable {
    let phoneNumber: String?
    let website: String?

enum CodingKeys: String, CodingKey {
    case website
    case phoneNumber = "formatted_phone_number"
}
}

并解析 Place.self

您还需要将“@escaping ([Details])”更改为“@escaping (Place)”