BaseJson4 1.07

BaseJson4 1.07

TestsTested
LangLanguage SwiftSwift
License MIT
ReleasedLast Release Aug 2018
SwiftSwift Version 4.0
SPMSupports SPM

Maintained by KittyMo.



  • By
  • KittyMei

BaseJson4

CocoaPods Platform

English

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 String --> Object Model
  • Object Model --> JSON String
  • Dictionary --> Object Model
  • Object Model --> Dictionary
  • 欄位異名對映
  • 日期指定格式轉換
  • 傾印 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. Object to 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" : "阿媛"
}

雖然欄位名稱不同了, 但仍然可以完美的對映到物件模型裡.