使用 Unsplash取得照片的照片牆
將照片牆的照片改成從網路取得,並將取得的資料儲存在手機中
這篇將上次做的照片牆稍做修改,以下列出增加的部分
- 將照片資訊從網路上抓下來(為 JSON格式)並把網路上抓下來的資料轉化成自訂格式 PhotoDetails
- 將自訂格式的 data儲存在手機的記憶體中
- 從手機中取得 data
- 將自訂格式的data解析成可以使用的格式
- 頁面在 PhotoCollectionViewController時隱藏 NavigationController
- 頁面在 SelectedPhotoViewController時顯示 NavigationController,讓作者名字顯示在上面
接著一一介紹怎麼達成的
將照片資訊從網路上抓下來(為 JSON格式)並把網路上抓下來的資料轉化成自訂格式 PhotoDetails
先使用 URLSession.shared 建立實體連線後,使用 dataTask 取得需要的資料data,取得後使用 JSONDecoder 解碼成自訂格式 PhotoDetails,在格式外加上 []是因為 data 是陣列,因為有可能解碼失敗所以使用 do try catch 擷取解碼失敗的錯誤。
這裡沒看過的部分是 @escaping以及 dataTask(with:completionHandler)這兩個東西:
>@escaping:由於 closure 會在 function 結束後就會拋棄,因此若想要將 closure 拿到 function外就必須要逃脫出來,這裡使用的英文就是 @escaping ,使用 escaping 的副作用就是在存取自己的屬性或方法時必須加上 .self。
> dataTask(with:completionHandler):completionHandler 會在任務完成後被呼叫,我想要將資料在取得資料這個 function 完成後傳送出去,因此加上 completionHandler。
getOnlineImagedata的 completionHander 會在 URLSession.shared.dataTask的 completionHandler 裡使用,dataTask 的 completionHanlder有加上 @esc-aping。
注意:若 getOnlineImagedata 的 completionHandler 沒加上@escaping則會在 function 完時就不能使用。
將自訂格式的 data 儲存在手機的記憶體中
userDefault 全名為 user default base,為 App 預設就有的 property list,在程式啟動後就會將資料載入到記憶體,能夠儲存上次 App 關閉時的狀態,可以使用 userDefault 中的 standard 屬性來進行儲存與讀取。
>userDefault.set(value:Any?, forkey: String):這邊的 Any 並非所有東西都能填,能填的有:數字. Data. Dictionary. Array. Date. String以及 URL,後面第二格代表儲存資料所對應到的鑰匙。
這裡因為不能直接儲存自訂格式,因此我先將格式使用 propertyEncoder 編碼成 data,接著存入 userDefault 中,最後編碼可能會失敗,所以使用try。
從手機中取得 data,並解析成可以使用的格式
>userDefault.string(forkey: String):只要將對應到先前儲存的 key 輸入,就能取得之前存入的資料。
這裡將 data使用 userDefault.string取得資料,取得後使用與編碼對應的解碼方法 PropertyDecoder解碼就能拿到資料。
在這裡使用 try?的方法嘗試,而非 try。差異在 try? 拋出錯誤訊息時不能得知錯誤訊息的種類,而使用 try 可以得知。
將自訂格式的 data 解析成可以使用的格式
使用 dataTask 取得圖片並轉成 UIImage並且取得其他資料,因為在 function外面也要使用這些資料,所以加上 escaping,最後記得要加上 phototask. resume() 讓任務開始執行。
取得資料後要將照片顯示在照片牆上,這裡的程式碼跳過。
頁面在 PhotoCollectionViewController 時隱藏 Navigation Controller
在選擇照片時並不需要 Navigation Controller 顯示作者姓名,因此將它隱藏,使用 setNavigationBarHidden 達成。
頁面在 SelectedPhotoViewController 顯示 Navigation Controller,讓作者名字顯示在上面
Navigation Controller 這部分大部分設定在 viewWillAppear 中,只有作者名字是在 viewDidLoad 時設定,作者名字是使用 navigationBar.topItem.title設定的。
這裡將 Navigation Controller 顯示出來,並且使用一張看不到的 image 當作 controller 的底圖,因此 controller 會變透明的,最後因為我將背景設定為黑色,所以把字呈現白色,可以使用 textAttributes 達成。
參考資料