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

Posted

技术标签:

【中文标题】如何使用 Codable 在 Swift 中使用动态文件名解析 JSON【英文标题】:How to parse JSON in Swift with dynamic filename using Codable 【发布时间】: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": "..."
            
         
     

【问题讨论】:

【参考方案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)

【讨论】:

以上是关于如何使用 Codable 在 Swift 中使用动态文件名解析 JSON的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Core Data 中使用 swift 4 Codable?

如何在 Swift 中使用 Codable 转换带有可选小数秒的日期字符串?

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

如何使用 Swift 创建 JSON Codable [关闭]

如何使用 Swift 的 Codable 编码成字典?

如何使用 Codable 和 Swift 解析这个嵌套的 JSON?