JSONNeverDie 使用指南

JSONNeverDie 是一个 Swift 写的 JSON 编码、解码库,利用反射实现 JSON 到 Model 的自动映射,无需任何 parse 代码,强大而简单。


Github 地址:https://github.com/johnlui/JSONNeverDie

JSONNeverDie 可以采用“子项目”或者“源代码”两种方式引入,本人更推荐前者,更好更新。以及,非常重要的一点,也是我做纯 Swift 开发两年以来(正好到今天两年整哈哈)的最佳实践:在 Swift 时代,一切包管理工具都是累赘,使用 git 手动管理第三方工程是最好的。

One more thing

多说一句,CocoaPods 这样的侵入性工具,我一开始就是拒绝的,经过这两年 Swift 翻天覆地的变化,想必各位都有了丰富的包管理工具蛋疼经历,此事就按下不表啦。

JSONNeverDie 在 2015年9月27日 发布了 0.1 版本,当时我所在的公司在开发一个 HTML5 小游戏平台,APP 中有许多的 model ,每一个都有许多的字段,写了一大堆 parse 代码的我感到一丝淡淡的忧伤:要是能够自动从 JSON 字符串映射到 model 字段就好了!加上 SwiftyJSON 有一些历史遗留问题,在处理过长非 JSON 字符时有偶发性闪退(若愚兄不要打我,来北京陪你喝酒),我便自己开发了这个 JSON 处理库。

15年底,按照计划,我离开了上家创业公司加入了住范儿,开始了为期 10 个月的“唯一程序员”生涯(10个月以后就有同伴啦)。刚开始,住范儿还处在找方向的阶段,快速开发可用原型成了我的首要工作,而当我第一次在全新 APP 中使用 JSONNeverDie 的自动映射功能的时候,我自己都要被自己感动哭了,简直太TM好用了!

后来,每做一个原型我就感动一次,有一天我突然明白,这个项目的使用示例太少了,严重阻碍了大家来用它,然后我就保留了这个信念直到今天,终于要付诸行动了,好开心!

基本架构

JSONNeverDie 只有两个元数据结构:struct JSONND 和 class JSONNDModel,分别对应 JSON 对象和 Model 对象。前者为值类型,完全的 Swift Style,主要用于 json["key"].int 这类的嵌套取值及类型转换,后者用于 Model 字段的自动映射,被迫使用了 class,继承了 NSObject。

JSONND 的使用

你可以使用字符串生成 JSONND 对象以便进行取值:

let jsonFromString = JSONND(string: "{\"name\": \"JohnLui\"}")

也可以使用 Array 或 Dictionary 生成 JSONND 对象以便得到 JSON 字符串:

let jsonFromArray = JSONND(array: ["love", "you", "guys"])
let jsonFromDictionary = JSONND(dictionary: ["love": ["you": "guys"]])

print(jsonFromArray.RAWValue)
print(jsonFromDictionary.RAWValue)

JSONNeverDie 之前支持从 Data 初始化,后来我想了想,这样太容易迷惑使用者。在跟 Pitaya 配合时,实际上 Pitaya 拿到的数据是 Data,首先被转换成了 String,再在 JSONNeverDie 内部被转换成 Data,最终生成 JSONND 对象,我认为这个性能损失是非常有价值的。我时刻谨记:代码是写给人看的,只是恰好能运行。同样,我的库是写给人用的,不是写来让机器跑的。

JSONNDModel 的使用

简单上手

我们使用上面生成的 `jsonFromString` 对象作为数据源,先定义 Model 类:

class Good : JSONNDModel {
    var des = ""
    override init(JSONNDObject json: JSONND) {
        // 记得要先调用父类的初始化
        // 自动映射实际上是在这一步完成的
        super.init(JSONNDObject: json)
        
        // 再获取你想要的字段并赋值
        // 此时可随意修改 Model 类
        self.des = json["description"].stringValue
    }
}

然后直接使用 JSONND 对象初始化这个类:

let people = People(JSONNDObject: jsonFromString)
print(people.name) // get "JohnLui"

That's it!

手动处理 Model 里属性名称和 JSON 中 key 值不一致的情况

class Good : JSONNDModel {
    var des = ""
    override init(JSONNDObject json: JSONND) {
        // 记得要先调用父类的初始化
        // 自动映射实际上是在这一步完成的
        super.init(JSONNDObject: json)
        
        // 再获取你想要的字段并赋值
        // 此时可随意修改 Model 类
        self.des = json["description"].stringValue
    }
}

需要注意的点

类型

JSON 标准支持四种基础类型和两种结构类型:

JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays).

- [rfc4627](https://www.ietf.org/rfc/rfc4627.txt)

这反映在 Swift 中就是 String、Int、Double、Bool、nil、Dictionary、Array。

自动映射唯一的要求

那就是要有初始值。有了初始值才会真正的分配内存空间,才能做到类型探测,才能自动映射。

Array 类型怎么办?

能怎么办?手动搞呗:

class TestModel: JSONNDModel {
    var string = ""
    var double = 0.0
    var int = 0
    
    var array_values = [Int]()

    override init(JSONNDObject json: JSONND) {
        // 完成 string double int 三个属性的自动映射
        super.init(JSONNDObject: json)

        // 手动完成数组赋值
        for i in json["array_values"].arrayValue {
            self.array_values.append(i.intValue)
        }
    }
}

JSONNDModel 对象嵌套?

手动搞,没问题,还支持嵌套对象数组呢:

class TestModel: JSONNDModel {
    var string = ""
    var double = 0.0
    var int = 0
    
    // 普通数组
    var array_values = [Int]()
    // 文艺数组
    var array = [ModelOnlyOneKey]()
    // 二逼...不对,是普通对象
    var hey: Hey!
    
    override init(JSONNDObject json: JSONND) {
        super.init(JSONNDObject: json)

        for i in json["array_values"].arrayValue {
            self.array_values.append(i.intValue)
        }
        for i in json["array"].arrayValue {
            self.array.append(ModelOnlyOneKey(JSONNDObject: i))
        }
        self.hey = Hey(JSONNDObject: json["hey"])
    }
}

多层对象嵌套

完全支持,Just Do It!

WRITTEN BY

avatar
2016.12.17   /   热度:80   /   分类: Auto Layout Club

发表评论:

© 2011-2017 岁寒  |  Powered by Emlog