美文网首页swift
swift 原生json解析探究与详解

swift 原生json解析探究与详解

作者: 追忆之丘 | 来源:发表于2021-01-08 11:06 被阅读0次

    swift 原生json解析探究与详解

    我们先构建一个json数据

    struct TextJson:Codable{
        let status: Int
        let text: String
    }
    

    然后我们生成json数据

    let makeModel = TextJson(status:10,text:"json")
    let jsonData = try JSONEncoder().encode(makeModel)
    

    打印一下json数据

    let jsonStr = String(data:jsonData, encoding: .utf8)
    print(jsonStr)
    //{"status": 10,"text":"json"}
    

    现在我们解析一下json数据

    let data = try JSONDecoder().decode(TextJson.self, from:jsonData)
    print(data)
    // TextJson(status:10, text:"json")
    

    如果我们解析的数据不存在怎么办?按照以前的情况,确实会报错,但是swift里面引入了可选类型,解决了这个问题

    我新建一个解析数据的model

    struct NewModel:Codable{
        let status: Int
        let text: String
        let isCheck: Bool
    }
    

    如果模型是这个样子,我们去解析jsonData的数据必出错,因为模型不匹配
    得益于可选类型,我们只需要稍做修改,即可修复这个bug

    struct NewModel:Codable{
        let status: Int
        let text: String
        let isCheck: Bool? //这里做了改动
    }
    let data = try JSONDecoder().decode(TextJson.self, from:jsonData)
    print(data)
    // TextJson(status:10, text:"json", isCheck: nil)
    

    现在报错的问题解决了,可是我们想给不存在的key增加一个默认值怎么办?比如我们想给isCheck的默认值设置为false,而不是没有这个key的时候是nil

    通过研究swift的JSONDecoder的源码,我们可以对KeyedDecodingContainer进行扩展,以满足我们的需求

    extension KeyedDecodingContainer{
     public func decodeIfPresent(_ type: Bool.Type, forKey key: K) throws -> Bool?{
        if let value = try? decode(type, forKey: key) {
            return value
        }
        
        return false
     }
    }
    

    然后我们在进行解析看看

    let data = try JSONDecoder().decode(TextJson.self, from:jsonData)
    print(data)
    //TextJson(status:10, text:"json", isCheck: Optional(false))
    

    我们惊喜的发现解析json数据的时候,当isCheck在jsonData里面不存在的时候,解析可以让ischeck有默认值false

    让class遵循Codable去解析json数据

    class TextClassJson: Codable{
        let status: Int
        let text: String
         
         init(status: Int, text:String){
            self.status = status
            self.text = text
         }
    }
    let data = try JSONDecoder().decode(TextClassJson.self, from:jsonData)
    print(data.status, data.text)
    // 10 json
    

    如果我们也想让上面的model解析isCheck这个不存在的key呢,

    class TextClassJson: Codable{
        let status: Int
        let text: String
        let isCheck: Bool
         init(status: Int, text:String, isCheck: Bool){
            self.status = status
            self.text = text
            self.isCheck = isCheck
         }
    }
    let data = try JSONDecoder().decode(TextClassJson.self, from:jsonData)
    print(data.status, data.text, data.isCheck)
    // 报错,因为没有与isCheck匹配的key
    

    我们如何修改?

    class TextClassJson: Codable{
        let status: Int
        let text: String
        let isCheck: Bool?
         init(status: Int, text:String){
            self.status = status
            self.text = text
         }
    }
    let data = try JSONDecoder().decode(TextClassJson.self, from:jsonData)
    print(data.status, data.text, data.isCheck)
    // 10 json Optional(false)
    

    相关文章

      网友评论

        本文标题:swift 原生json解析探究与详解

        本文链接:https://www.haomeiwen.com/subject/epgxaktx.html