SwiftData 作為 Apple 推出的現代化持久化框架,旨在簡化開發者管理本地資料庫的複雜度。在最新的版本更新中,SwiftData 針對開發者在實務上最常遇到的幾個痛點進行了優化,特別是在處理外部資料類型、UI 分組呈現以及非 SwiftUI 環境下的資料監控等方面。
突破第三方類型的儲存限制
在之前的 SwiftData 版本中,如果你想在模型中使用一個自定義類別,該類別必須被標記為 @Model 才能被 SwiftData 識別並生成對應的資料庫結構(Schema)。然而,在實際開發中,我們經常需要儲存來自第三方套件或 iOS SDK 的類型,這些類型是由外部定義的,開發者無法修改其原始碼來加上 @Model 標記,導致無法直接將其納入持久化模型中。
為了解決這個問題,新版本引入了 Codable 屬性支持。只要該第三方類型符合 Codable 協定(即可以被編碼與解碼為 JSON 或二進位格式),開發者就可以透過在屬性上標記 .codable 屬性,將其直接儲存在模型中。這意味著 SwiftData 會將這些複雜的對象視為一塊不透明的資料(Opaque Value)進行儲存,而不需要為其建立獨立的資料表。
不過,這種做法是有代價的。由於資料被視為不透明,你無法在查詢時對這些 Codable 屬性進行過濾(Filtering)或排序(Sorting)。此外,如果第三方類型的結構發生變化(例如增加了一個欄位),SwiftData 無法自動執行資料遷移(Migration)。因此,對於自己可以控制的類型,建議依然使用 @Model;只有在面對無法修改的外部類型時,才使用 Codable 方案。
簡化 SwiftUI 的分組顯示
在開發列表介面時,我們經常需要將資料依照某個欄位進行分組(例如將行程按目的地分組)。以往這需要開發者在獲取資料後,手動在記憶體中對陣列進行分組運算,邏輯較為繁瑣。
現在 SwiftData 擴展了 @Query 屬性包裝器,新增了 sectionBy 參數。開發者只需指定一個 Key Path(路徑),SwiftData 就會在底層自動處理分組邏輯。透過訪問該查詢對象的 sections 屬性,可以直接在 SwiftUI 的 List 中使用 ForEach 進行嵌套迭代,大幅減少了 UI 層的邏輯代碼量。
將資料觀察機制脫離 SwiftUI
長期以來,@Query 是 SwiftData 與 UI 綁定的核心,但它只能在 SwiftUI 的 View 中使用。這對那些需要將業務邏輯抽離到 Controller 或 ViewModel 的開發者,或是使用 SceneKit 等非 SwiftUI 框架的專案來說是一個限制。
為此,新版本推出了 ResultsObserver。它的功能與 @Query 幾乎一致,支持排序、過濾與分組,但它可以在任何 Swift 類別中使用。ResultsObserver 建立在 Observation 框架之上,允許開發者在非 View 環境下監控資料庫變動,並在資料更新時觸發特定的計算或邏輯處理。
除了單次查詢的觀察,新版本還加入了 HistoryObserver。這個工具是用來監控持久化歷史記錄(Persistent History)的。每當資料庫有新的交易(Transaction)提交時,HistoryObserver 的 eventCounter 屬性會隨之增加。這對於需要將本地資料庫與遠端伺服器保持同步的應用程序至關重要,因為開發者可以透過監控這個計數器,精準地知道哪些資料發生了變更,進而調用 fetchHistory API 來獲取增量更新,而不需要重新同步整個資料庫。
總結與實務建議
這次的更新讓 SwiftData 從一個單純的 UI 綁定工具,演進為一個更完整的資料管理方案。對於 Junior 工程師來說,理解這幾個新特性的核心在於:Codable 解決了外部依賴的儲存問題,sectionBy 優化了呈現效率,而 ResultsObserver 與 HistoryObserver 則將資料驅動的邏輯從 UI 層解放出來,讓架構設計能更靈活地實踐關注點分離。
來源:infoq.com
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。