Try   HackMD

新人資訊

技術-iOS #10-Local Persistence,本地端儲存

學習主題如下:

  1. 利用系統內建物件 UserDefaults,可以儲存基本類型資料,包含 array。
  2. 利用系統內建 document 目錄,可以將客製物件經過 encode 轉成 plist file 型式儲存。
  3. CoreData,這是由 swift 將 SQLLite 包裝轉換成物件模型的儲存模組。

先下載課程提供的專案骨架:https://github.com/appbrewery/Todoey-iOS13 ,此專案幾乎是空的,所以一開始從元件庫拉一個全新的 UIViewController,它是由一個 TableView and a Prototype Cells 組成,本專案演練的應用情境是一個 ToDo List,只需要一個頁面,所以將原本的頁面刪除,將此新頁面設成「起始頁面」,並將全來的 ViewController 更名為 TodoListViewController,並繼承系統內建的 UITableViewController。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

建立 View and Controller 的關聯:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

第一種最簡單的儲存方式就是 UserDefaults,可以在 Controller 宣告總體變數
let defaults = UserDefaults.standard,將 TodoList 存在一個 itemArray (string array) 裏,項目異動時執行 self.defaults.set(self.itemArray, forKey: "TodoListArray"),在 viewDidLoad() 事件中把它讀出,達到 App 關掉後重開仍能保有資料的目的,整個應用程序非常簡單。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

第二種方式是為了儲存「客製化物件」,因為 TodoList 的項目不僅是一個字串,若要加入一個完成與否的 flag,UserDefaults 就無法支持了,因此就要比較麻煩的執行 encode 後再儲存,儲存位置也需要在系統規範有權限的位置,以下就是抓出 document directory 的方法,順便在其中塞入一個 plist file:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

物件定義中必須 implement protocol Codable

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

先要實作 TableView 相關的 method,確認資料顯示正確:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

在新增按鈕觸發時跳出對話筐,確認後儲存,程式碼如下,save() 時必須經過 encode:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

另外新增一個互動功能,就是點選項目時,toggle done 這個欄位,並立刻儲存一次:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

在 viewDidLoad() 加上 loadItems(),此時是 decode,這樣就完成應用流程。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

執行的樣子如下:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

第三種儲存方法為 Core Data,是 swift 以 SQLLite 為底層而包裝起來的物件模型,使用起來不需要關心 SQLLite 如何儲存,只要面對 Object 的世界即可。使用方法是先「新增物件模型」,以下列模板新增 file:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

點選 data file 會出現 swift 提供的物件結構設計畫面,把他加入兩個屬性 title and done:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

為了在 App 啟動時引入物件模型,必須在 AppDelegate.swift import Core Data 並加入一些程式碼,因為系統提供 Core Data 的專案模版,我們可以以此模板另外新增一個測試專案,再把程式 copy 過來,可達到一樣的效果。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

如此一來已經可以在專案中使用此物件了,相對於一般物件的建立方法,Core Data 的物件建立方法稍有不同,但也非常類似:let newItem = ItemX(context: self.context),其中 context 必須先宣告成總體變數:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

save() 則省掉 encode 程式,顯得更精簡:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

load() 程序則改成資料庫查詢語法:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

最後附帶再做一個功能:搜尋。拉一個 Search Bar 元件:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

以 extension 方式對 Controller 加入對 UISearchBarDelegate 這個 protocol 的參照,實作兩個方法如下,分別處理 search button 按下去的行爲,執行對 Core Data 資料庫的查詢,和 search text 字元變動時的行為,特別針對欄位清空時讓 UI 元件恢復起初狀態:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

執行狀況如下:

https://youtu.be/xIRQl0hssjU

以上對 Core Data 做了基礎的演練,除此之外,本地端儲存方法還有 Realm,待下階段再續。

By Newman Chen 2022/8/28

後記 2022/8/31
試著新增一個 Entity 「Category」,並建立一對多關聯到 Item,發現 Category 名稱與內建物件重複,為避免困擾欲更名為 ItemCategory,結果似乎系統底層不允許更名,搞很久還是 compile error,稍微窺探一下後面章節 Realm,似乎是更好的本地端儲存方案,可以完全取代 Core Data 的功用,心裡差不多已經放棄 Core Data 了,砍掉吧,哈哈。