作業#62 Random User

目的:練習串接API下載資料以及將資料儲存在documentsDirectory

功能

  1. 串接RandomAPI獲取50筆資料並按照A~Z的順序載入到清單上
  2. 利用UIRefreshControl下拉TableView重新下載50筆資料
  3. 可搜尋關鍵字尋找是否有相同名稱的使用者
  4. 點擊後跳轉頁面顯示詳細資料,並包含Map顯示使用者座標
  5. 可將喜愛的資料加入到收藏夾中,並保存起來也可進行刪除
  6. 網路有問題的時候抓不到資料會跳出通知

API

單一資料:

可從下方網址獲取一個隨機的User

https://randomuser.me/api/

多筆資料:

可從下方網址獲取指定數量的多筆資料,我則是一次下載50筆,因此在數量的位置輸入50

https://randomuser.me/api/?results=\(數量)

解析JSON資料

按照API顯示的JSON資料自訂資料型別

UserListController

將下載功能另外寫在UserListController,這個Controller純負責下載

  1. 聲明static常數shared,透過這個常數直接使用內部function
  2. fetchRandomUser的completion參數使用ResultType回傳出下載結果

下載後A~Z排序

將資料裡的firstName用for迴圈按照順序比對是否符合,再放進另一個空的Array

let letters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]

遇到的問題:一開始用比對的方式會遇到有些使用者名稱不是A~Z的字母,有可能會有其他國家的文字

解決方法:後來詢問了一下Peter,可以將不是A~Z名稱的放到最後面,因此append跟insert兩種不同方式加入資料,一開始先辨別每個使用者名稱按照順序比對符合的就插到最前面,這裡用到reversed是因為越後面插進去的資料才會在越前面,因此要從Z開始比對這樣最後比對到A才會在最前面,再來用比對有沒有開頭不是A~Z的,有的話用append加在Array的最後面

下拉TableView完成資料更新

這個我們可以使用UIRefreshControl辦到

  1. 加入refresh到tableView
  2. 設定refreshControl觸發使用的function,重新下載資料以及清空搜尋列
  3. .endRefreshing要加入不然refreshControl會一直出現在上半部

UIRefreshControl參考連結:

搜尋關鍵字

在tableView上方加入SearchBar,使用SearchBar輸入關鍵字

建立承接搜尋結果的空陣列

var searchResults = [RandomUser.Results]()

加入UISearchBarDelegate這個protocol後使用 searchBarSearchButtonClicked(_ searchBar: UISearchBar),這個function去定義按下搜尋後要做些什麼

  1. 先檢查最一開始下載的資料以及SearchBar裡究竟有沒有東西
  2. 使用for迴圈比對每筆資料的firstName或lastName有沒有符合關鍵字
  3. 如果有的話加入到searchResults中,沒有的跳出通知

UITableViewDataSource、UITableViewDelegate

先判斷目前是否有下載到資料,然後判斷目前searchResults中是否有東西,如果有東西代表目前是有搜尋的,就顯示搜尋的結果出來,每次重新下載資料或是清空SearchBar都會把searchResults清空

跳轉頁面顯示資料以及地圖

傳送資料

自訂資料型別使用UITableViewDelegate的didSeletRowAt將使用點擊的資料包進去,最後使用IBSegueAction傳送過去,IBSegueAction就不贅述了,詳細可以參考下方連結

IBSegueAction參考連結:

地圖MapKit View

  1. import MapKit
  2. 先把資料中的座標放進CLLocationDegrees轉換成顯示座標的型別
  3. 設定MapKit View的region包含顯示座標以及顯示大小
  4. 加入MKPointAnnotation,將大頭針放在User的座標上,並設定大標題跟副標題,最後加入到Map中
import MapKit

點擊收藏

先自訂要儲存的資料型別以及加入儲存及讀取的功能在裡面

每當按下收藏按鈕就將該筆資料存進儲存的Array中,並移除掉該筆資料

然後將讀取資料放在ViewDidAppear,因為我們可能會在收藏頁面移除掉我們要取消收藏的資料,再切換回來清單頁面要再重新讀取

收藏夾刪除資料

先設定可編輯,然後如果編輯模式是刪除的話,就移除Array中的資料以及做出移除Cell的動畫

儲存資料的Array每當有產生改變都會觸發儲存,所以每次改動刪除或新增資料都不需要另外儲存

網路問題

在前面有說過使用ResultType定義下載成功失敗,下載只要失敗就會丟出錯誤

然後使用function將丟出來的function用Alert提醒使用者,在使用者按下Alert上的按鍵後會重新下載資料

操作畫面

--

--