如何为动态键,json解析,swift5创建模型 [英] How to create a Model for dynamic keys , json parsing ,swift5

查看:81
本文介绍了如何为动态键,json解析,swift5创建模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在解析json数据并尝试创建模型,但无法弄清楚如何实现标题并从json数据(我提供)中提取属性,作为 pageids 属性是动态的.请告诉我如何创建模型以使用ID(存储在 pageids 属性中)从页面提取 title 属性

I am parsing a json data and trying to create a Model but can't figure out how to achieve the title and extract properties from the json data (which I have provided), as pageids property is dynamic. Please tell me how can I create Model to extract the title property from the page using id (stored in pageids property)

链接我尝试了一下,下面是我的代码,但我认为那是不正确的

I tried little a bit, below is my code but I don't think that's correct

var ID = ""
struct Document:Codable {
    
    let batchcomplete:String
    let query:Query
}
struct Query:Codable {
    let normalized:[Normalized]
    
    let pages:Pages
    
    var pageids:[String]{
        didSet{
            ID = oldValue[0]
        }
    }
    
}

struct Normalized:Codable {
    let from:String
    let to:String // it is a name of an flower
}
struct Pages:Codable {
    let id:[Pages2]
    enum CodingKeys:CodingKey {
        case id = "\(ID)"
    }
}
struct Pages2:Codable {
    let title:String // this is an official name of flower
    let extract:String // this is a body
    let thumbnail:Thumbnail
}
struct Thumbnail:Codable {
    let source:String //this is an url for photo
}

推荐答案

用于映射JSON的模型如下所示:

The model to map your JSON will be something like this:

struct Document: Codable {
    let batchcomplete: String
    let query: Query
}

struct Query: Codable {
    let normalized: [Normalized]
    var pageids: [String]
    let pages: [String: Page]
}

struct Normalized: Codable {
    let from: String
    let to: String
}

struct Page: Codable {
    let title: String
    let extract: String
    let thumbnail: Thumbnail
}
struct Thumbnail: Codable {
    let source: String
}

,您可以使用 pageids 数组和 pages 词典访问每个页面:

and you have access to each page using pageids array and pages dictionary:

let decoder = JSONDecoder()
do {
    let decoded = try decoder.decode(Document.self, from: Data(jsonString.utf8))
    decoded.query.pageids.forEach { id in
        guard let page = decoded.query.pages[id] else { return }
        print(page.title)
    }
} catch {
    print(error)
}

但是,我希望对模型进行一些小的更改,以便更轻松地访问页面.这将需要自定义实现 Query 结构的解码:

However I would prefer to make a small change to the model in order to make access to pages easier. That will require to customly implement the decoding of Query struct:

struct Query: Decodable {
    let normalized: [Normalized]
    let pages: [Page]
    
    enum CodingKeys: String, CodingKey {
        case normalized
        case pageids
        case pages
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        normalized = try container.decode([Normalized].self, forKey: .normalized)
        
        let pageids = try container.decode([String].self, forKey: .pageids)
        let pagesDict = try container.decode([String: Page].self, forKey: .pages)
        pages = pageids.compactMap { pagesDict[$0] }
    }
}

然后,访问每个页面就像循环一样简单:

Then, access to each page would be as simple as a loop:

let decoder = JSONDecoder()
do {
    let decoded = try decoder.decode(Document.self, from: Data(jsonString.utf8))
    decoded.query.pages.forEach { page in
        print(page.title)
    }
} catch {
    print(error)
}

这篇关于如何为动态键,json解析,swift5创建模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆