嘗試從網路抓取並顯示圖片

使用 URLSessionDataTask抓資料以及的 JSONDecoder來做分析資料

分析資料有很多種方式來分析,可以使用第三方函式庫來分析,也能使用apple在 swift4中提供的 codable protocol達成,這次不是取很複雜的東西(e.g. 像是影音檔),所以就先不使用第三方函式庫。

首先找個 API,由於要做類似 10 years challenge APP(一種使用很多圖片的 APP),所以就用 Unsplash API,接下來先申請個帳號,申請完按下 New Application

接著要確認一些重要事項,記得打勾

寫上要用在什麼樣子的 APP上

接著就能拿到 key了

key不能洩漏給別人

拿到 API key之後參考一下文件網址寫法,除了 cliend_id之外其他都是選填, order_by有三種排序方式可以選, latest. oldest. popular, per_page則是可以設定資料數

https://api.unsplash.com/photos/?client_id=YOUR_ACCESS_KEY
&order_by=ORDER&per_page=NUMBER_OF_PHOTOS

接著將網址送出就能拿到結果,可以看到有一堆字

將資料貼在 JSON Editor Online這個網站就能看到資料的結構

看得到總共有20筆資料
找了一下發現有 URL可供使用,可以直接連到圖片,還有各種解析度的圖

我們需要 urls裡的 regular作為圖片連結, created_at作為時間,alt_description作為圖片解釋,user裡面的 first_name當作作者名稱

取得資料之後接下來要先能夠在 xcode上顯示,可以用 URLSessionDataTask來達成,URLSession是使用 thread來做事,會在背景執行,因此不會干擾主要在執行的程式。

從網路上取得JSON資料

用 URLSession.shared來建立實體以供連線,接著使用 dataTask (with: completionHandler:)來取得(data, response,error)三種資料,資料會傳到閉包裡面,在閉包裡就能分析取得的資料,最後記得要用 resume()執行剛才所指派的任務。

取得資料之後,由於是 JSON格式不會在console上顯示,為了要顯示出來,必須將它轉為 String(使用第4到5行的 String(data: data, encoding: .utf8))。

結果就會出現取得的資料

定義 JSON資料的格式

取得資料後必須分析資料才能拿來使用,分析前必須先將想要取得資料的型別先定義出來,這樣程式在分析時才不會不了解型別導致出錯。

swift4在解析 JSON時要先將 JSON的 Dictionary變成一個自訂的型別,這個型別必須遵守 Codable(代表可以解碼跟編碼)或者 Decodable protocol最後將 Dictionary中的 key(像是在 Unsplash API中的 create_at)轉換型別。

因為我們要使用上述的四種資料( urls裡的 regular, created_at,alt_description與 user裡面的 first_name ),所以在定義型別時要定義出來,其餘用不到的可以省略。

若 JSON第一層是 array([])與 JSON第一層為 object({})的定義資料型別是相同的方法,差異就只有 array在使用時要加上[],下方就是我定義的型別

定義時,如果是 object(以 dictionary格式表達,被 { } 包著),宣告格式時就不需要加上 [ ] ,若是 array(使用 [ ] 包著),宣告型態時就要加上 [ ]

宣告後接著就先測試看看是否能將型別套用在網路上抓下來的資料

使用這段程式碼能夠看自己寫出的架構是否有錯誤
抓成功之後就會取得4項參數

這邊貼一個抓失敗的例子,錯誤訊息寫說 Expected to decode Array but found a dictionary instead,意思就是原本定義是期望著拿到 Array<Any>的格式,但是在抓資料時卻找到 dictionary,怎麼回事?看一下定義的方法

發現了在 user這邊定義格式為自訂的格式 info Array,但是 info的格式從網頁上看到的是 dictionary,因此必須將代表 Array的 [ ] 拿掉才是正確的。

當型態宣告錯誤,又沒有將 error 顯示出來,那麼怎麼找都找不到錯誤
user這個地方是使用 dictionary代表的 object ( [ ] ),而非 array( { } )

將 JSON資料轉化成自訂型別 Photos

成功分析 JSON資料後,就能開始嘗試將資料轉化成自訂型別,程式碼與上方定義 JSON格式的程式大同小異,只是多了 JSONDecoder,用來將 JSON格式轉換成 [Photos],加上 [] 是因為資料型態原本就是陣列。

decoder.decode(想要生成的型別,資料) → 這邊使用 .self 來傳入想要生成的型別

DateDecodingStrategy這邊使用國際標準 iso 8601

將資料轉化後,一筆一筆的列印出來
可以看到資料分開了,大成功

使用 UIImage從 URL取得照片

最後把 URL從資料裡面取出,將URL經過 URLSession.shared.dataTask取得資料後就能夠使用 UIImage來顯示

用 photo加上 ” . “就能看到剛才定義的型別,用 photo.urls.regular取得連結

最後有出現可怕的紫色問題,所以加上 DispatchQueue.main.async讓程式跑在 main Queue中

結果

請忽略圖片以外的元件,這是個半成品,目前只是將照片顯示在 ImageView上

Github

--

--