【KakaJSON手册】01_JSON转Model_01_基本用法
在iOS开发中,后台返回的数据大多是JSON格式,对应地会被网络框架层解析成Swift中的Dictionary、Array。由于数据类型的复杂、字段的繁多,直接使用Dictionary、Array会比较麻烦,比如
items[0]["user"]["name"]
这样的使用方式,非常不友善,而且没有智能语法提示。所以很多时候会考虑将JSON转换成Model之后再进行操作,会友善很多,比如items[0].user.name
。
- Swift内置了一套Codable机制,可以用于JSON转Model。对于一些简单的模型结构,还是挺好用,但一旦牵扯到复杂的模型结构、一些个性化的需求(比如KeyMapping、类型不匹配时的转换处理、自定义解析规则等),Codable就无法友善地完成任务了。
- 为了解决上述问题,我编写了一套纯Swift实现的JSON与Model互相转换的框架:KakaJSON,本人非常喜欢龙珠,框架取名自Kaka Rotto(卡卡罗特,孙悟空)。基于之前编写过OC版本的JSON\Model转换框架MJExtension的经验,绕过了很多坑,编写过程也比较顺利。对外提供了一些友善易用、可扩展的接口,内置了Metedata缓存等机制,加快转换速度。
- 本教程是为了让大家能够快速上手KakaJSON的使用,挖掘它内部的各种功能,发挥它的最大威力。未来也可以会推出一些源码分析的文章。
最简单的Model
import KakaJSON
// ① 让模型类型遵守`Convertible`协议
struct Cat: Convertible {
var weight: Double = 0.0
var name: String = ""
}
let json: [String: Any] = [
"weight": "Miaomiao",
"name": 6.66
]
// ② 直接调用json的model方法,传入模型类型,返回模型实例
let cat = json.kk.model(Cat.self)
print(cat?.name) // Miaomiao
print(cat?.weight) // 6.66
// 或者也可以调用一个全局函数来完成字典转模型
let cat2 = model(from: json, Cat.self)
Any.Type
// 有时类型可能是个变量,比如
var type: Any.Type = Cat.self
// 调用带有anyType参数的方法即可
// 由于传入的类型是Any.Type,所以返回值类型是Any,到时根据需求强制转换成自己想要的类型
let cat = json.kk.model(anyType: type) as? Cat
// 或者调用全局函数
let cat2 = model(from: json, anyType: type) as? Cat
JSONString
// jsonString可以是String、NSString、NSMutableString
let jsonString: String = """
{
"name": "Miaomiao",
"weight": 6.66
}
"""
// 跟JSON的用法是一样的
let cat = jsonString.kk.model(Cat.self)
let cat2 = model(from: jsonString, Cat.self)
var type: Any.Type = Cat.self
let cat3 = jsonString.kk.model(anyType: type) as? Cat
let cat4 = model(from: jsonString, anyType: type) as? Cat
Model嵌套
// 让需要进行转换的模型都遵守`Convertible`协议
struct Book: Convertible {
var name: String = ""
var price: Double = 0.0
}
struct Car: Convertible {
var name: String = ""
var price: Double = 0.0
}
struct Dog: Convertible {
var name: String = ""
var age: Int = 0
}
struct Person: Convertible {
var name: String = ""
var car: Car?
var books: [Book]?
var dogs: [String: Dog]?
}
let json: [String: Any] = [
"name": "Jack",
"car": ["name": "BMW7", "price": 105.5],
"books": [
["name": "Fast C++", "price": 666.6],
["name": "Data Structure And Algorithm", "price": 1666.6]
],
"dogs": [
"dog0": ["name": "Larry", "age": 5],
"dog1": ["name": "ErHa", "age": 2]
]
]
// 就是如此简单,不用再做额外的操作
let person = json.kk.model(Person.self)
print(person?.car?.name) // BMW7
print(person?.books?[1].name) // Data Structure And Algorithm
print(person?.dogs?["dog0"]?.name) // Larry
Model数组
struct Car: Convertible {
var name: String = ""
var price: Double = 0.0
}
// json数组可以是Array<[String: Any]>、NSArray、NSMutableArray
let json: [[String: Any]] = [
["name": "Benz", "price": 98.6],
["name": "Bently", "price": 305.7],
["name": "Audi", "price": 64.7]
]
// 调用json数组的modelArray方法即可
let cars = json.kk.modelArray(Car.self)
print(cars?[1].name) // Bently
// 同样的还有其他方式
let cars2 = modelArray(from: json, Car.self)
var type: Any.Type = Car.self
let cars3 = json.kk.modelArray(anyType: type) as? [Car]
let cars4 = modelArray(from: json, anyType: Car.self) as? [Car]
// 另外,jsonString转为Model数组,也是如此简单
let jsonString = "...."
let cars5 = jsonString.kk.modelArray(Car.self)
let cars6 = modelArray(from: jsonString, Car.self)
let cars7 = jsonString.kk.modelArray(anyType: type) as? [Car]
let cars8 = modelArray(from: jsonString, anyType: Car.self) as? [Car]