BaseJson4
英文
BaseJson4 能够让您轻松地将 JSON 字符串转换为对象模型,同样也能将模型转换为 JSON 字符串
* 此软件包仅适用于 Swift 4.0 以上
为什么使用它?
当我们调用一个 Service API 时,后端服务器通常会返回一个 JSON 字符串,而在 Swift 3 中,只能将其转换为字典(Dictionary)或数组(Array),直到现在 Swift 4 才能直接将其转换为一个自定义的对象模型,这个软件包让您轻松使用 Swift 4 的这一特性。
和使用旧方法相比,可能看起来像这样
if let statusesArray = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]],
let user = statusesArray[0]["user"] as? [String: Any],
let username = user["name"] as? String {
// Finally we got the username
}
如果您使用过 SwiftyJSON,看起来可能像这样
let json = JSON(data: dataFromNetworking)
if let userName = json[0]["user"]["name"].string {
//Now you got your value
}
但仍有一个缺点,字段名称必须手动输入,例如上面示例中的 ["user"],手动输入名称有可能出现错别字,或者一时忘记完整名称。
那么,使用 BaseJson4 后看起来可能像这样
if let user = jsonStr.toObj(type: User.self) {
// 直接使用 User 物件, User 可以是一個 Class 或 Struct
print("user.name=\(user.name)")
let age = user.age
}
以操作对象属性的方式来使用数据字段,大大减少了因手动输入错误而产生的bug
系统需求 Requirements
- iOS 9.0+ | macOS 10.10+
- Xcode 9
- Swift 4.0
功能特徵 Features
- JSON 字串 --> 对象模型
- 对象模型 --> JSON 字串
- 字典 --> 对象模型
- 对象模型 --> 字典
- 字段别名映射
- 日期指定格式转换
- 打印 Object 内容
如何安装 使用CocoaPods (iOS 9+, OS X 10.10+)
你可以使用 CocoaPods 来安装,将 BaseJson4
添加到你的 Podfile
platform :ios, '9.0'
use_frameworks!
target 'MyApp' do
pod 'BaseJson4'
end
如何安装 手动Manually
- 下载本套装的 BaseJson4.swift 文件
- 把这个文件加入你的 xcode 项目里
- 安装完成
如何使用 Usage
1. Json to Object
我们先用一段 Json字符串 来示范
{"id":66, "birthday":"1997-05-08", "height": 180.61, "name":"小軒", "gender":"M", "age": 29, "friends": [ {"name":"小明", "isFriend": true}, {"name":"小華", "isFriend": false, "test":1} ]}
首先先建立对象模型(Model),这里我们使用 class,当然你也可以使用 struct
class User: BaseJson4 {
var name: String? = nil
var gender: String? = nil
var age: Int = 0
var birthday: String? = nil
var friends: [Friend]? = nil
var height: Double = 0
}
class Friend: BaseJson4 {
var name: String? = nil
var isFriend: Bool = false
}
Json数据来源类型可以是 String 或 Data 或 Dictionary
BaseJson4 为 String/Data/Dictionary 添加了一个扩展功能叫做 toObj
例如
let jsonStr = "{\"id\":66, \"birthday\":\"1997-05-08\", \"height\": 180.61, \"name\":\"小軒\", \"gender\":\"M\", \"age\": 29, \"friends\": [ {\"name\":\"小明\", \"isFriend\": true}, {\"name\":\"小華\", \"isFriend\": false, \"test\":1} ]}"
if let user = jsonStr.toObj(type: User.self) {
let desc = user.description() // description()可以傾印出此物件的所有屬性值
print("物件內容 ==> \(desc)")
// .... 已經可以直接使用物件了
let age = user.age
let name = user.name
if let friends = user.friends {
for friend in friends {
print("friend name=\(friend.name)")
}
}
}
我们已经成功地把一段 Json字符串 转成了一个 对象Model,转换只需要一行代码 String.toObj
输出的 log 如下
物件內容 ==>
<User:
name=Optional("小軒")
gender=Optional("M")
age=29
birthday=Optional("1997-05-08")
friends=Array count=2 [ <Friend: name=Optional("小明") isFriend=true>, <Friend: name=Optional("小華") isFriend=false> ]
height=180.61
>
friend name=Optional("小明")
friend name=Optional("小華")
是不是很简单容易呢
Json字符串中有一项叫做 birthday,它是一个生日日期,我们可能希望它能直接转换成一个 Date 对象
接下来我们示范如何使用日期格式
首先把我们 User 对象的 birthday 改成 Date 类型
class User: BaseJson4 {
var name: String? = nil
var gender: String? = nil
var age: Int = 0
var birthday: Date? = nil // <--- 改成 Date類型
var friends: [Friend]? = nil
var height: Double = 0
static func dateFormats() -> [String: String]? {
return [CodingKeys.birthday.stringValue: "yyyy-MM-dd"] // <--- 指定格式為yyyy-MM-dd
}
}
这样一来 birthday 就变成了一个 Date 对象了
修改后输出的 log 如下
物件內容 ==>
<User:
name=Optional("小軒")
gender=Optional("M")
age=29
birthday=Optional(1997-05-07 16:00:00 +0000)
friends=Array count=2 [ <Friend: name=Optional("小明") isFriend=true>, <Friend: name=Optional("小華") isFriend=false> ]
height=180.61
>
2. 对象转Json
接下来我们要如何将一个对象输出成 json 字符串呢?
很简单,同样只需要一行代码
let jsonStr = user.toJson()
print("輸出的 json 字串 = \(jsonStr)")
print 结果如下
輸出的 json 字串 = {"age":29,"gender":"M","friends":[{"name":"小明","isFriend":true},{"name":"小華","isFriend":false}],"name":"小軒","birthday":"1997-05-08","height":180.61000000000001}
默认是适合传递给api的紧凑格式,如果你希望生成适合人类阅读的 json,可以加上参数
let jsonStr = user.toJson(.prettyPrinted) // <--- 加上 prettyPrinted 參數
加上参数后的 print 结果变成这样
輸出的 json 字串 = {
"age" : 29,
"gender" : "M",
"friends" : [
{
"name" : "小明",
"isFriend" : true
},
{
"name" : "小華",
"isFriend" : false
}
],
"name" : "小軒",
"birthday" : "1997-05-08",
"height" : 180.61000000000001
}
3. 异名对应
有时候 API 返回的 JSON 字段名字可能不符合 Swift 的命名习惯,这时候可以使用异名对应
我们用一段简单的 JSON 字串来示范
{"user_id":66, "user_name":"阿媛", "valid":true, "sex":"F", "style":"村菇"}
字段 user_name 我们希望改成 name,user_id 希望改成 userId
修改 User 物件模型,加上 CodingKeys
class User: BaseJson4 {
var userId: Int = 0
var name: String? = nil
var gender: String? = nil
var valid: Bool = false
var style: String? = nil
// 重設CodingKeys來進行異名對映
enum CodingKeys : String, CodingKey {
case userId = "user_id" // 異名對映
case name = "user_name" // 異名對映
case gender = "sex" // 異名對映
case valid // 同名
case style // 同名
}
}
但这里有一点要特别注意的,一旦重设了 CodingKeys 做异名对应,就必须每个字段都设上去,同名的字段也不能省略哦!
转换的代码则仍然和之前一样,没有改变
let jsonStr = "{\"user_id\":66, \"user_name\":\"阿媛\", \"valid\":true, \"sex\":\"F\", \"style\":\"村菇\"}"
print("輸入的 json 字串 ==> \(jsonStr)")
// json字串 --> Object
if let user = jsonStr.toObj(type: User.self) {
let desc = user.description()
print("物件內容 ==> \(desc)")
// Object --> json字串
let ss = user.toJson(.prettyPrinted)
print("輸出的 json 字串 = \(ss)")
}
print印出的结果如下
輸入的 json 字串 ==> {"user_id":66, "user_name":"阿媛", "valid":true, "sex":"F", "style":"村菇"}
物件內容 ==>
<User:
userId=66
name=Optional("阿媛")
gender=Optional("F")
valid=true
style=Optional("村菇")
>
輸出的 json 字串 = {
"sex" : "F",
"style" : "村菇",
"user_id" : 66,
"valid" : true,
"user_name" : "阿媛"
}
尽管字段名称不同了,但仍然可以完美地对应到物件模型里。