將 JSON 轉換成 Codable 自訂型別的 10 秒驗證方法

串接第三方 API,將 JSON 以 JSONDecoder 轉換成自訂的 Codable 型別是許多 App 上常見的功能。不過初學者剛開始常在定義 JSON 對應的 Codable 型別時出問題,因此彼得潘接下來將以從 iTunes API 抓取蔡淳佳的好聽情歌為例,分享如何利用 Postman,Development Assets & Code snippet 十秒驗證 Codable 型別的方法。

用 Postman 下載 JSON 資料

點選 Send and Download 下載。(ps: 如果後台還不能串接,也可以拜託後台大大先給我們假資料的 JSON 檔。)

將 JSON 檔存到專案的 Development Assets 下

將 songs.json 放到 Development Assets 下的 Preview Assets.xcassets,取名為 songs。

如果 Development Assets 下沒有 xcassets,記得先從 File > New > File 選擇 Asset Catalog 建立 xcassets。

定義 JSON 對應的資料型別

import Foundation

struct Song: Codable {
var artistName: String
let trackName: String
var previewUrl: URL
var artworkUrl100: URL
let trackPrice: Double?
}

struct SongResults: Codable {
var resultCount: Int
var results: [Song]
}

用 JSONDecoder 將 JSON 轉換成自訂型別

func testGetSongs() {
guard let data = NSDataAsset(name: "songs")?.data else {
print("data not exist")
return
}
do {
let decoder = JSONDecoder()
let result = try decoder.decode(SongResults.self, from: data)
print(result)
} catch {
print(error)
}
}

呼叫 function testGetSongs,轉換成功時將印出抓到的歌曲內容。

而當轉換失敗,比方我們不小心將 let trackName: String 寫成 let trackNeme: String 時,將印出以下錯誤。

keyNotFound(CodingKeys(stringValue: "trackNeme", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "results", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"trackNeme\", intValue: nil) (\"trackNeme\").", underlyingError: nil))

關於錯誤訊息的解讀,可參考以下連結。

利用 Code snippet 10 秒測試

讓我們再回頭看看轉換 JSON 的 function testGetSongs。我們發現無論串接哪個 API,需要調整的只有下方粗體的三個地方。

func testGetSongs() {
guard let data = NSDataAsset(name: "songs")?.data else {
print("data not exist")
return
}
do {
let decoder = JSONDecoder()
let result = try decoder.decode(SongResults.self, from: data)
print(result)
} catch {
print(error)
}
}

因此我們可以把它變成 code snippet,方便未來十秒驗證 JSON 對應的 Codable 型別是否正確。

我們將剛剛程式裡需要使用者輸入的地方換成以 <# #> 包含的placeholder。

func test<# api name #>() {
guard let data = NSDataAsset(name: "<# name #>")?.data else {
print("data not exist")
return
}

do {
let decoder = JSONDecoder()
let result = try decoder.decode(<# codable type #>.self, from: data)
print(result)
} catch {
print(error)
}
}

Xcode 會自動把 <# #> 包含的文字變成長方形的輸入框。

將 function 的程式碼整個選取後,從右鍵選單選擇 Create Code Snippet。

將 code snippet 取名為 Decode JSON Check,設定 Completion 欄位,將輸入的快速鍵設為 decodejson。

有了剛剛發明的 snippet,我們可以從 Snippets library 加入 Decode JSON Check,或是手動輸入 deco,從自動完成選單裡選擇 decodejson。

Cool,現在我們只要在三個框框輸入內容,即可實現 10 秒測試 Codable 型別的不可能任務 !

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com