代码之家  ›  专栏  ›  技术社区  ›  Aaron Bratcher

如何从字典中生成可解码对象?

  •  0
  • Aaron Bratcher  · 技术社区  · 7 年前

    我希望有一个可以通过普通可编码协议或字典实例化的结构(现有代码需要字典实例化)。

    我在操场上有这段代码,但我不确定在需要字典的第二次初始化中要做什么。如何从字典生成解码器对象?

    import Foundation
    
    public protocol Parsable: Decodable {
        init(dict: [String: Any]) throws
    }
    
    struct LinkModel: Parsable {
        var href: String
        var text: String
    
        init(dict: [String: Any]) throws {
            href = "/store/options.aspx"
            text = "Buy"
        }
    }
    
    struct ResponseModel: Parsable {
        var link: LinkModel?
        let showCell: Bool
    
        enum CodingKeys : String, CodingKey {
            case link
            case showCell = "show"
        }
    
        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
    
            let linkResponses = try container.decode([LinkModel].self, forKey: .link)
            link = linkResponses.first
    
            showCell = try container.decode(Bool.self, forKey: .showCell)
        }
    
        init(dict: [String: Any]) throws {
            let jsonData = try JSONSerialization.data(withJSONObject: dict, options: [])
            let decoder = ??? // what do I do here?
            self.init(from: decoder)
        }
    }
    
    
    let jsonText = """
    {
        "show": true,
        "link": [
            {
            "text": "Buy",
            "href": "/store/options.aspx"
            }
        ]
    }
    """
    
    // test standard Decodable instantiation
    let jsonData = jsonText.data(using: .utf8)!
    let model = try! JSONDecoder().decode(ResponseModel.self, from: jsonData)
    
    print(model.link?.href)
    
    // test dictionary instantiation
    ...
    
    2 回复  |  直到 7 年前
        1
  •  9
  •   wadda_wadda Ranuj Mahajan    7 年前

    伸出你的手 Parsable 自动生成要查找的初始值设定项的协议。

    extension Parsable {
        init(dict: [String: Any]) throws {
            let jsonData = try JSONSerialization.data(withJSONObject: dict, options: [])
            let decoder = JSONDecoder()
            self = try decoder.decode(Self.self, from: jsonData)
        }
    }
    
        2
  •  3
  •   mfaani    7 年前

    你走对了路。

    import Foundation
    
    public protocol Parsable: Decodable {
        init(dict: [String: Any]) throws
    }
    
    struct LinkModel: Parsable {
        var href: String
        var text: String
    
        init(dict: [String: Any]) throws {
            href = "/store/options.aspx"
            text = "Buy"
        }
    }
    
    struct ResponseModel: Parsable {
        var link: LinkModel?
        let showCell: Bool
    
        enum CodingKeys : String, CodingKey {
            case link
            case showCell = "show"
        }
    
        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
    
            let linkResponses = try container.decode([LinkModel].self, forKey: .link)
            link = linkResponses.first
    
            showCell = try container.decode(Bool.self, forKey: .showCell)
        }
    
        init(dict: [String: Any]) throws {
            let jsonData = try JSONSerialization.data(withJSONObject: dict, options: [])
            // 1.
            let decoder = JSONDecoder()
            // 2. 
            let result = try decoder.decode(ResponseModel.self, from: jsonData)
            // 3. 
            self = result
    
    
        }
    }
    
    
    let jsonText = """
    {
        "show": true,
        "link": [
            {
            "text": "Buy",
            "href": "/store/options.aspx"
            }
        ]
    }
    """
    
    // test standard Decodable instantiation
    let jsonData = jsonText.data(using: .utf8)!
    let model = try! JSONDecoder().decode(ResponseModel.self, from: jsonData)
    
    print(model.link?.href)
    

    1. 创建一个JSONdecoder对象。
    2. ResponseModel
    3. 将解码结果分配给 self 自己
    推荐文章