Swift-咖啡店App Part.4

兼距API串接與使用者資料儲存

--

前言:

目前進度來到私房店家的部分,考慮後續想將API上資料加入私房店家的清單中,決定私房店家的分類仿照網路資訊的分類方式,在資料儲存上也稍微簡單些。

製作過程先是建立基本的CRUD功能,再依據最終決定的儲存方式修改程式碼,雖然可能某部分CRUD的程式碼到最後會不存在,但不失為一次讓自己重新複習的機會。

在一開始CRUD部分則是參考先前在Peter課程期間做的咖啡豆庫存紀錄App作業,但不會使用到UserDefaults的部分。

Step1. 基本架構

如前言所述,在私房店家的分類與網路資訊相同,故先建立固定的第一層縣市分類的table view,下一層以空白方式呈現,讓使用者可以自行添加自己的私房店家。

Step2. 加入新店家

增加店家部分使用unwind segue的方式完成,在編輯頁面則是用UITableViewController來呈現。

圖片部分藉由UIImagePickerController來帶出相簿或相機的功能,同時需至設定info.plist增加使用相機與存取相簿的權限,此外,需藉由遵從UIImagePickerControllerDelegate以及UINavigationControllerDelegate,並使用imagePickerController(_:didFinishPickingMediaWithInfo:)得知使用者選取的照片進而顯示在畫面上。

其他欄位資訊部分,大多以label與text field的方式呈現,較為不一樣之處則是縣市的欄位,將text field設定為無法點擊的狀態,強迫使用者使用picker view進行選取,以方便後續資料的管理。

必填項目標題有反紅打星號,也有設卡關機制,送出後若有未填會以alert方式提示。

Step3. Read & Edit

Read部分直接模仿與API相同的格式,在程式碼上也大同小異,只是多了個note欄位,而在map view部分,考慮到使用者在使用手機時不方便查詢目標的經緯度,所以改用地址方式去做map view的顯示。

Edit部分,原先在咖啡豆庫存紀錄App中是以點擊cell後進入編輯頁面,但點擊cell部分已被Read使用,且為了更貼近使用者的操作,改在detail頁面增加一個Edit的Bar Botton Item。

當點擊後跳至加入店面的頁面,但會同時將資料都帶過去同時包含當時的indexPath.row的數值,在unwind segue需判斷是編輯狀態還是新增狀態,前者以取代方式呈現,後者以插入array方式呈現。

Step4. Delete

Delete部分直接參考先前的作業,使用tableView(_:commit:forRowAt:),產生左滑cell跑出delete選項。

Step5. 導入Firebase的database與Storage

整體概念如下:

  1. 利用database得資料結構,collections>docuements>field來建構每個使用者獨自的資料庫
  2. 基本的新增、讀取、刪除、修改功能
  3. 照片部分則需用到storage功能,獲得網址後,可以在進入指定city的collection後獲得所有的documents資料,也可藉由fields裡面的網址下載圖片並顯示在App中

在資料結構上會以登入的使用者ID當作起始collection,避免每個使用者的清單資料全都攪和在一起,大致概念如下

=>userID (c) > cities (d) > taipei (c) > cafe ID (d) > cafe detail data(f)

首先,建立儲存資料的功能,需先增加imageURL與date兩項變數至UserCafeDatas的struct當中。

調整清單頁面unwind segue的IBAction內容

儲存資料部分是選用setData的語法,在路徑上第一層的document是使用optional binding定義的userID,利用官方語法獲得目前登入帳號的email,以達成每個使用者只能讀取到自己建立的清單。

在NewCafeTableViewController,重新調整prepare及imagePickerController(_:didFinishPickingMediaWithInfo:)函式內的程式碼,前者補上回傳的資料,讓其含有date與imageURL,而date部分會判斷是否目前是nil的情況,用來區分是新增狀態還是修改狀態 ; 後者則是增加上傳到storage並獲得下載URL的程式碼,特別是在圖片部分刻意壓縮到0.3,減低後須讀取資料的所需時間,若是使用者未選擇照片,則在儲存資料時就會使用一組defaultURL替代。

儲存後database的畫面
儲存後storage的畫面

接著完成讀取資料的部分,建立一個loadCafeData的函式並在viewDidLoad內讀取,loadCafeData使用了排序與監聽的語法,可以自訂排序方式並在新增資料後立即更新畫面。

增加兩筆資料後database畫面
增加兩筆資料後storage畫面,其中一筆使用defaultURL

刪除部分則是利用delete()完成,將原先tableView(_:commit:forRowAt:)的內容進行小修改即可,storage部分還需考慮是否是使用defaultURL

刪除使用defaultURL資料後的database畫面
刪除使用defaultURL資料後的storage畫面
刪除第二筆資料後的database畫面
刪除第二筆資料後的storage畫面

最後就是修改部分,這部分會利用一個布林值editMode的變數來判斷目前是修改狀態或新增狀態,預設為flase,在viewDidLoad讀取資料部分除了增加date、photoImageURL及storage外,將editMode設為true

先利用source.editMode判斷狀態,true時進行修改flase則進行新增,修改則是使用update()達成

以上就是這階段的進度,不得不說在修改功能部分一直卡關,而且常常完成一個功能就會發現有漏的部分,整體大致上都完成了私房店家的基本功能,但仍有很多改善的地方,如搜索功能、程式碼的精簡、私房店家讀取資料時有時未按照定義的排序、整體介面的優化等!

下一步驟預計將About部分完成(雖然應該沒什麼內容),同時研究一下其他額外的功能!

firebase部分可以參考以下Peter的文章

而storage部分除了Peter的文章,appcoda這一篇也值得參考

其他部分則是以下

--

--