您的位置:首页 > Web前端 > JavaScript

【KakaJSON手册】01_JSON转Model_01_基本用法

2019-08-14 17:22 3003 查看

在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

Class类型

class Cat: Convertible {
var weight: Double = 0.0
var name: String = ""
// 由于Swift初始化机制的原因,`Convertible`协议强制要求实现init初始化器
// 这样框架内部才可以完整初始化一个实例
required init() {}
}
let json = ...
let cat = json.kk.model(Cat.self)

struct Dog: Convertible {
var weight: Double = 0.0
var name: String = ""
// 由于编译器自动帮结构体类型生成了一个init初始化器
// 所以不需要自己再实现init初始化器
}

struct Pig: Convertible {
var weight: Double
var name: String
// 如果没有在定义属性的同时指定初始值,编译器是不会为结构体生成init初始化器的
// 所以需要自己实现init初始化器
init() {
name = ""
weight = 0.0
}
}

let属性

// KakaJSON也支持let属性
struct Cat: Convertible {
let weight: Double = 0.0
let name: String = ""
}
let json = ...
let cat = json.kk.model(Cat.self)

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]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: