如何使用Codable使用动态文件名在Swift中解析JSON

问题描述 投票:0回答:1

我正在尝试将以下JSON解析为一个类,但不知道如何处理这种特殊情况。

这里是api:https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=&explaintext=&indexpageids&titles=bird

我正在尝试获取标题和摘录,但是要这样做,需要我经过唯一的pageid。我如何使用可编码协议来做到这一点?

{ 
    "batchcomplete": "", 
    "query": { 
        "normalized": [
           {
               "from": "bird",
               "to": "Bird"
           }
         ],
         "pageids": [
             "3410"
         ],
         "pages": {
            "3410": {
                "pageid": 3410,
                "ns": 0,
                "title": "Bird",
                "extract": "..."
            }
         }
     }
}
json xcode parsing codable
1个回答
0
投票

我的建议是编写一个自定义初始化程序:

pages解码为[String:Page]字典,并根据pageids中的值映射内部字典>

let jsonString = """
{
    "batchcomplete": "",
    "query": {
        "normalized": [
           {
               "from": "bird",
               "to": "Bird"
           }
         ],
         "pageids": [
             "3410"
         ],
         "pages": {
            "3410": {
                "pageid": 3410,
                "ns": 0,
                "title": "Bird",
                "extract": "..."
            }
         }
     }
}
"""

struct Root : Decodable {
    let query : Query
}

struct Query : Decodable {
    let pageids : [String]
    let pages : [Page]

    private enum CodingKeys : String, CodingKey { case pageids, pages }

    init(from decoder : Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.pageids = try container.decode([String].self, forKey: .pageids)
        let pagesData = try container.decode([String:Page].self, forKey: .pages)
        self.pages = self.pageids.compactMap{ pagesData[$0] }
    }
}

struct Page : Decodable {
    let pageid, ns : Int
    let title, extract : String
}


let data = Data(jsonString.utf8)

do {
    let result = try JSONDecoder().decode(Root.self, from: data)
    print(result)
} catch {
    print(error)
}
© www.soinside.com 2019 - 2024. All rights reserved.