【问题标题】:How to parse JSON in Swift with dynamic filename using Codable如何使用 Codable 在 Swift 中使用动态文件名解析 JSON
【发布时间】:2020-04-15 07:11:54
【问题描述】:

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

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

我正在尝试获取标题并提取,但为此,我需要通过唯一的 pageid。我将如何使用 Codable 协议来做到这一点?

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

【问题讨论】:

    标签: json xcode parsing codable


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 2020-07-28
      • 1970-01-01
      • 1970-01-01
      • 2019-05-06
      • 2019-03-03
      • 1970-01-01
      • 2020-01-14
      • 1970-01-01
      相关资源
      最近更新 更多