【Swift】Codable (Model ⇔ Dictionary)、(Array<Model> ⇔ Array<Dictionary>)

该文章详细介绍了Swift中使用Codable协议进行JSON数据与模型之间的转换,包括Data、String和Dictionary的相互转化。同时,文章提到了CodingKeys用于解决JSON键与Swift属性名冲突的问题,以及在解码过程中可能出现的DecodingError类型错误、valueNotFound、keyNotFound和dataCorrupted等错误及其含义。
摘要由CSDN通过智能技术生成

代码

import Foundation

struct YZWJsonExtension {
    //MARK: - decode
    /// 解码入口。type传入AnyClass.self 。
    public static func decode<T>(type: T.Type, object: Any?) throws -> T? where T : Decodable {
        if let object = object, let data = YZWJsonExtension.decode(object: object) {
            return YZWJsonExtension.decode(type: type, data: data)
        }
        return nil
    }
    
    /// 将object转成data
    public static func decode(object: Any) -> Data? {
        if let data = object as? Data {
            return data
        } else if let string = object as? String {
            return string.data(using: .utf8)
        }
        return try? JSONSerialization.data(withJSONObject: object)
    }
    
    /// codable
    private static func decode<T>(type: T.Type, data: Data) -> T? where T : Decodable {
        do {
            let object = try JSONDecoder().decode(type, from: data)
            return object
        } catch {
            
            if let jsonStr = String(data: data, encoding: .utf8) {
                print(jsonStr)
            }
            
            switch error {
            case let DecodingError.typeMismatch(_, context):
                print("数据类型错误:", context.codingPath, context.debugDescription, separator: "\n\n", terminator: "\n")
            case let DecodingError.valueNotFound(_, context):
                print("找不到value:", context, separator: "\n", terminator: "\n\n")
            case let DecodingError.keyNotFound(_, context):
                print("找不到Key:", context, separator: "\n", terminator: "\n\n")
            case let DecodingError.dataCorrupted(context):
                print("Json格式错误:", context, separator: "\n", terminator: "\n\n")
            default:
                print("Decode出现未知异常")
            }
        }
        return nil
    }
    
    //MARK: - encode 编码
    /// model, models -> type类型
    public static func encodeJsonObject<T>(model: T) -> Any? where T : Encodable {
        if let data = try? JSONEncoder().encode(model) {
            return try? JSONSerialization.jsonObject(with: data)
        }
        return nil
    }
    
    /// model, models转成json data
    public static func encodeData<T>(model: T) -> Data? where T: Encodable {
        return try? JSONEncoder().encode(model)
    }
}

使用Codable必要条件

要使用Codable需要满足:

  1. 对象为structclass类型,并继承Codable对象。
  2. 如果存储的属性有enumstructclass类型,也必须继承Codable对象。

转换原理

使用Codable进行模型与字典、模型数组与字典数组的互转都是需要将对象转成Data类型,通过Data类型来进行转换。

Data是一串Json(NSJSONWritingPrettyPrinted)格式的字符串,使用UTF8编码转成的Data

JsonString to Data

jsonString.data(using: .utf8)

Array or Dictionary to Data

JSONSerialization.data(withJSONObject: object)

Array or Model to Data

JSONEncoder().encode(model) // model 为Array<Model>或Model

Data to JsonString

String(data: data, encoding: .utf8)

Data to Array or Dictionary

JSONSerialization.jsonObject(with: data)

Data to Array or Model

JSONDecoder().decode([Model].self, from: data) // Array<Model> , [Model] 也可以写成 Array<Model>
JSONDecoder().decode(Model.self, from: data) // Model

CodingKeys(Json的key与语言的声明冲突)

enum CodingKeys: String, CodingKey {
	case yourKey = "jsonKey"
}

以上代码是将Json中jsonKey这个名称替换成yourKey。这样就可以避免名称冲突。
只需将需要替换的Key进行设置,如果没有存在需要修改的Key,那么这个enum可以不写

报错

DecodingError.typeMismatch(_, context)

数据类型错误

DecodingError.valueNotFound(_, context)

找不到value,当这个Value在声明的时候没有定义成可选?,那么如果value为空值则会报这个错。

DecodingError.keyNotFound(_, context)

找不到Key,当这个Key在声明的时候没有定义成可选?,那么Json中不包含这个Key则会报这个错。

DecodingError.dataCorrupted(context)

Json格式错误

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值