還記得在第3單元,我們透過 iTune 與芝加哥藝術博物館兩個提供Open API的網站,學習網路程式設計,其中 iTune 主要提供音樂資料庫(超過5千萬首歌曲),而芝加哥藝術博物館則有非常豐富的視覺藝術(30多萬件藏品)。

上一課所學的圖片輪播正適合展示藝術作品,所以本單元第2個App就來改寫3-4b的芝加哥藝術博物館,一方面將網路程式改成async/await非同步語法,另一方面操作模式也改用上一課的圖片輪播,以展示博物館精美畫作。

第一部分先修改3-4b的網路程式,這部份是透過 API 搜尋畫家名字取得作品列表,原來是比較舊的寫法:

guard let myURL = myURLComponent.url else { return }
URLSession.shared.dataTask(with: myURL) { 回傳資料, 回傳碼 , 錯誤碼 in
    if let 解碼資料 = 回傳資料 {
        do {
            let 解碼結果 = try JSONDecoder().decode(搜尋結果.self, from: 解碼資料)
            print(回傳碼 ?? "No response")
            作品列表 = 解碼結果.data
        } catch {
            print("JSON解碼錯誤")
        }
    } else {
        print(錯誤碼 ?? "No error")
    }
}

早期 URLSession.share.dataTask() 的用法,在上一單元3-1b詳細說明過。若改成新的 async/await 非同步語法,會變得更簡潔,可讀性更高,如下:

if let myURL = myURLComponent.url {
    let (內容, 回傳碼) = try await URLSession.shared.data(from: myURL)
    print(回傳碼)
    let 解碼結果 = try JSONDecoder().decode(搜尋結果.self, from: 內容)
    return 解碼結果.data
}

這段程式碼放在 async throws 函式「搜尋作品列表」裡面,語法雖然簡單,其中關鍵在於 async/await 以及 throws-try 的用法,背後對應的「非同步」與「錯誤處理」的觀念非常重要,有疑問的話,請複習第3單元7, 8兩課內容。

func 搜尋作品列表(_ artist: String) async throws -> [搜尋品項] {
    var myURLComponent = URLComponents()
    myURLComponent.scheme = "https"
    myURLComponent.host = "api.artic.edu"
    myURLComponent.path = "/api/v1/artworks/search"
    myURLComponent.query = "q=\\(artist)&limit=20"
    if let myURL = myURLComponent.url {
        let (內容, 回傳碼) = try await URLSession.shared.data(from: myURL)
        print(回傳碼)
        let 解碼結果 = try JSONDecoder().decode(搜尋結果.self, from: 內容)
        return 解碼結果.data
    }
    return []
}

函式裡面有兩行用到 try 的地方,表示可能會有錯誤發生,第一個可能是網路抓不到資料,第二個可能是內容格式不合,導致傑森解碼器出錯。若遇到任何錯誤發生,則會拋出錯誤,立即從函式返回,不再往下執行。

第二部分改用「圖片輪播」,會在後面陸續完成。本節先引進一個SwiftUI物件:Picker 選擇器。

原先在3-4b我們設計一個「搜尋框」,讓使用者輸入藝術家名稱來搜尋作品,這樣雖然很有彈性,但對於不熟悉西洋藝術的使用者來說,可能不知道該搜尋什麼。

截圖 2022-07-17 下午9.14.52.png

博物館藏品雖多,但其實還是有限的,未必涵蓋每個畫家,無限制的搜尋不見得都有效,不如將其藏品的「關鍵字」做一個列表,讓使用者選擇,每個選擇一定會有對應作品,這樣App體驗效果會更理想。

所以我們用Picker物件來做一個選單,裡面列出博物館收藏的畫家名字,讓使用者容易選擇。Picker 的基本用法如下:

Powered by Fruition