Swift 4.1 中的 Codable 改進

BigNerdCoding發表於2018-02-24

2018-2-24.jpeg

Apple 在 Swift 4.0 中作了很多的改進,其中我個人最喜歡的就是 Codable 協議的出現。它讓 Swift 自帶了 JSON 、 XML 結構化資料和 Model 的對映和轉換能力。

Codable 最常見的使用場景就是:APP 發起網路請求,然後我們將服務端響應的 JSON 資料轉換為對應的 Model 實體。由於服務端的程式設計規範可能與客戶端存在差異, Codable 預設資料轉換實現可能不再適用。例如,服務端可能使用的蛇形命名方式而客戶端使用的是駝峰。此時我們就需要在客戶端自己動手實現對映關係。

struct Mac: Codable {
    var name: String
    var screenSize: Int
    var cpuCount: Int
}

let jsonString = """
[
    {
	"name": "MacBook Pro",
        "screen_size": 15,
        "cpu_count": 4
    },
    {
        "name": "iMac Pro",
        "screen_size": 27,
        "cpu_count": 18
    }
]
"""

let jsonData = Data(jsonString.utf8)

let decoder = JSONDecoder()

do {
    let macs = try decoder.decode([Mac].self, from: jsonData)
    print(macs)
} catch {
    print(error.localizedDescription)
}
複製程式碼

上訴程式碼並不能完成理想的解碼操作,因為 Codable 的預設實現無法將蛇形變數名對映到對應的駝峰屬性上。所以在 Swift 4.0 中我們需要對 Mac 進行部分改造:

struct Mac: Codable {
    var name: String
    var screenSize: Int
    var cpuCount: Int

    enum CodingKeys : String, CodingKey {
          case name
          case screenSize = "screen_size"
          case cpuCount = "cpu_count"
    }
}
複製程式碼

好在 Swift 4.1 對此作出了改進。現在我們可以通過設定 *JSONDecoder * 的 keyDecodingStrategy 就能實現不同程式設計規範之間解碼操作了。與之對應,JSONEncoder 也有一個 keyEncodingStrategy 屬性用於不同程式設計規範之間的編碼操作。所以上訴程式碼可以簡化為:

struct Mac: Codable {
    var name: String
    var screenSize: Int
    var cpuCount: Int
}

let jsonString = """
[
    {
	"name": "MacBook Pro",
        "screen_size": 15,
        "cpu_count": 4
    },
    {
        "name": "iMac Pro",
        "screen_size": 27,
        "cpu_count": 18
    }
]
"""

let jsonData = Data(jsonString.utf8)

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

do {
    let macs = try decoder.decode([Mac].self, from: jsonData)
    print(macs)
} catch {
    print(error.localizedDescription)
}
複製程式碼

如果你想進行反向轉換操作的話,程式碼也非常簡單:

let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
let encoded = try encoder.encode(macs)
複製程式碼

當然,我們還可以對轉換策略進行自定義實現以其實現一些特定需求。具體的使用方式可以參照程式碼

相關文章