Swift Xcode 解析 JSON

串接第三方 API,解析 JSON 資料,轉換成自訂型別顯示

陳薇帆 Vivienne Chen 2020/12/24 15:40:06
302

目的

學習利用 URLSession 抓取後台的 JSON 資料,利用 JSONDecoder 和 Codable 將 JSON 資料生成自訂型別。

流程

以 iTunes 搜尋 Taylor Alison Swift 當例子,API 的網址為

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

後台回傳的資料利用網站 JSON Editor Online 顯示後如下:

依照 iTunes 回傳的 JSON 可以看出資料架構,第一層是 object,object key results 的資料是 array,array 裡裝了許多歌曲 object。

因此定義了型別 SearchResponse 對應第一層的 object, StoreItem對應歌曲的object,並將 property results 的型別宣告為 [StoreItem],說明它是 array。

這裏將 SearchResponse & StoreItem 分開定義:

struct SearchResponse:Codable {
    let resultCount: Int
    let results: [StoreItem]
}
struct StoreItem:Codable {
    let artistName: String
    let trackName:String // 曲名
    let collectionName:String? // 專輯名稱
    let previewUrl:URL
    let artworkUrl100:URL // image url
    let trackPrice:Double?  // 價錢
    let releaseDate:Date 
    let isStreamable:Bool?
}

其中,StoreItem依照回傳值來設定參數型別,部分 property 被宣告為 optional,因為 JSON 裡有些 key 不會每一筆資料都有,像是trackPrice,不是每首歌都可以買,所以不一定有 trackPrice。因此將不一定會有的 collectionName、trackPrice 及isStreamable 設為 optional。如果沒有設為 optional,到時候一旦發現沒有這些欄位,將造成轉換失敗。

從回傳的資料得知時間格式採用 iso8601

獲取回傳資料:

    func fetchItem(searchString:String) {
        if let urlStr = "https://itunes.apple.com/search?term=\(searchString)&media=music".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), // 如果是中文字,需要轉成%形式
           let url = URL(string: urlStr) {
            URLSession.shared.dataTask(with: url) { (data, response , error) in
                //利用 JSONDecoder 的 function decode 將 Data 型別的 JSON 資料變成型別 SearchResponse 的資料
                let decoder = JSONDecoder()
                decoder.dateDecodingStrategy = .iso8601 // 設定時間格式
                if let data = data {
                    do {
                        let searchResponse = try decoder.decode(SearchResponse.self, from: data)
                        self.items = searchResponse.results
                        DispatchQueue.main.async {
                            self.tableView.reloadData()
                        }
                    } catch {
                        print("error")
                    }
                } else {
                    print("error")
                }
            }.resume()
        }
    }

先使用URLSession.shared.dataTask建立從網路抓取資料的任務,呼叫resume()執行此任務,取得data後利用 JSONDecoder 的 function decode 將 Data 型別的 JSON 資料轉換成自定義型別 “SearchResponse” 的資料。

在 StoryBoard 建立一個 TableViewController 用以顯示音樂清單:

TableViewCell使用自訂格式:

import UIKit

class MusicListTableViewCell: UITableViewCell {

    @IBOutlet weak var trackImageView: UIImageView!
    @IBOutlet weak var musicNameLabel: UILabel!
    @IBOutlet weak var musicPriceLabel: UILabel!
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
}

 

顯示音樂清單結果如下:

 

 

陳薇帆 Vivienne Chen