#20 新手的 Swift JSON decode 練習題
Published in
7 min readAug 16, 2022
利用 apple marketing tools RSS generator 練習 JSON decode
這次的練習單純將條件限縮在查詢台灣地區的各類音樂類型 TOP50的歌單
功能
- 可選擇不同的音樂類型 (Albums / Music Videos / Playlists / Songs)
- 選好類型將會自動於背景取得TOP 50的音樂資訊
- 按下按鍵將取得的音樂資訊,排入 Table View 中顯示 (有用到 Kingfisher 套件顯示音樂圖片)
步驟
- 拉一個主頁面及一個Table頁面
2. 依API回傳的資料,去設定 JSON decode 需要用到的資料格式(建立music.swift)
struct SearchResponse: Decodable {
let feed: Feed
}struct Feed: Decodable {
let title: String
let results: [Item]
}struct Item: Decodable {
let artistName: String?
let name: String
let releaseDate: String?
let artworkUrl100: URL?
let url: URL?
}
3. 設置 IBOutlet 及 參數
@IBOutlet weak var picker: UIPickerView!
var items = [Item]()var pickerData = ["Albums", "Music Videos", "Playlists", "Songs"]
let musicTypes = ["albums", "music-videos", "playlists", "songs"]
4. 設置 IBAction 及 各函式
在 ViewController中 @IBSegueAction func show(_ coder: NSCoder) -> MusicTableViewController? {
guard items.count > 0, let controller = MusicTableViewController(coder: coder) else {return nil}
controller.items = items
return controller
}
func fetchItems(type: String) {
if let url = URL(string: "https://rss.applemarketingtools.com/api/v2/tw/music/most-played/50/\(type).json") {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data {
do {
let decoder = JSONDecoder()
let searchResponse = try decoder.decode(SearchResponse.self, from: data)
DispatchQueue.main.async {
self.items = searchResponse.feed.results
}
} catch {
print(error)
}
}
}.resume()
}
}extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
print(musicTypes[row])
let type = musicTypes[row]
self.fetchItems(type: type)
}
}在 MusicTableViewController中override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "\(MusicTableViewCell.self)", for: indexPath) as? MusicTableViewCelllet music = items[indexPath.row]
cell?.photoView.kf.setImage(with: music.artworkUrl100, placeholder: UIImage(systemName: "music.note"))
cell?.musicLabel.text = music.artistName
cell?.songLabel.text = music.name
cell?.rowLabel.text = "\(indexPath.row + 1)"
return cell!
}