#43 使用 JSONDecoder 把 JSON 轉換成自訂型別的資料

使用 iTunes 搜尋 swift 當例子,API 網址如下

https://itunes.apple.com/search?term=swift&media=music

首先確認回傳的JSON資料,可使用下列網址操作

第一層資料

可以看到第一層資料有兩個Key,resultCount 與 results,results 內又有50筆資料

使用 struct 自訂第一層資料格式,命名為 SearchResponse,兩個參數內容名稱必須與JSON回傳的Key一模一樣,資料的格式也要對應

// 第一層struct SearchResponse: Codable {let resultCount: Intlet results: [StoreItem]}

第二層資料

第二層資料內有需多歌曲資訊,不過裡面沒有再包物件,可以判斷這個JSON為兩層

使用 struct 自訂第二層資料格式,命名為 StoreItem,內容參數可以取自己需要的就好,不過可能為 nil 的參數要使用 optional 在類型後面加上 ? ,並把第二層的型別 StoreItem 補給第一層資料

// 第二層struct StoreItem: Codable {let trackId:Intlet artistId:Intlet trackName:Stringlet collectionName:String?let previewUrl:URLlet artworkUrl100:URLlet trackPrice:Double?let releaseDate:Datelet isStreamable:Bool?}

透過 API 抓取 JSON 資料 並轉換成自訂型別

// 讓下載在背景執行寫法
func useUrlSession(){
// 網址全英文寫法
let urlString = "https://itunes.apple.com/search?term=swift&media=music&country=tw"

if let url = URL(string: urlString) {
//使用 URLSession.shared 讓下載在背景執行
// dataTask 回傳抓資料的任務

URLSession.shared.dataTask(with: url) { data, response, error in
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
if let data{
do{
let searchResponse = try decoder.decode(SearchResponse.self, from: data)
}catch{
print("error")
}
}else{
print("error")
}
}.resume()
}
}

程式碼解釋

初始化一個 JSONDecoder 並將 日期格式設定為 .iso8601

let decoder = JSONDecoder()decoder.dateDecodingStrategy = .iso8601

使用 do catch 判斷抓取資料是否成功,透過 JSONDecoder 將 data 轉換為自訂的 SearchResponse 型別

if let data{
do{
let searchResponse = try decoder.decode(SearchResponse.self, from: data)
}catch{
print("error")
}
}else{
print("error")
}

成功的話可以透過 print 將資料印出

print("searchResponse.results \(searchResponse.results)")

讀取第一筆資料,確認我們所定義的參數都有值

print("first \(searchResponse.results[0])")

也可以指定某個參數內容

print("previewUrl : \(searchResponse.results[0].previewUrl)")

參考資料

--

--