BaseJson4 1.07

BaseJson4 1.07

测试已测试
语言语言 SwiftSwift
许可 MIT
发布最新发布2018年8月
SwiftSwift版本4.0
SPM支持SPM

KittyMo维护。



  • KittyMei

BaseJson4

CocoaPods Platform

英文

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

  1. 下载本套装的 BaseJson4.swift 文件
  2. 把这个文件加入你的 xcode 项目里
  3. 安装完成

如何使用 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" : "阿媛"
}

尽管字段名称不同了,但仍然可以完美地对应到物件模型里。