Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SwiftDataのカスタムデータストアを試してみた

1mash0
April 26, 2025

 SwiftDataのカスタムデータストアを試してみた

Nagoya.swiftの時間余ったら枠で登壇

1mash0

April 26, 2025
Tweet

Other Decks in Programming

Transcript

  1. SwiftDataのカスタムデータストアって? • WWDC2024で発表されたSwiftDataの新機能 • SwiftDataはデフォルトだとCore Dataを利用して永続化が行われる • 新しいDataStoreプロトコルを利用することで独自の永続化レイヤを実装することが 可能 ◦

    JSONファイルからWebサービス、データベースエンジンまで、さまざまな種類の永続化に 対応 ◦ SwiftUIおよびSwiftDataのモデリングコードを変更する必要がない https://developer.apple.com/jp/xcode/swiftdata/
  2. DataStore protocol DataStore : AnyObject iOS 18.0+ | iPadOS 18.0+

    | Mac Catalyst 18.0+ | macOS 15.0+ … An interface that enables SwiftData to read and write model data without knowledge of the underlying storage mechanism. SwiftData が、基盤となるストレージの仕組みを知らなくてもモデルデータの読み書きを可能にする インターフェース。(ChatGPT 訳)
  3. DefaultSnapshot struct DefaultSnapshot iOS 18.0+ | iPadOS 18.0+ | Mac

    Catalyst 18.0+ | macOS 15.0+ … DataStoreSnapshotの具象型 DataStoreSnapshotを指定する場面で、余程のことじゃなければこれを使えばいい気が する
  4. データストアをJSONファイルに変えてみる 「Create a custom data store with SwiftData」でもJSONファイルを例にしている • final

    class JSONStore: DataStore { … } • final class JSONStoreConfiguration: DataStoreConfiguration { … } • DataStoreSnapshotはDefaultSnapshotを使ってる
  5. JSONStore • typealias Snapshot = DefaultSnapshot ◦ @Modelを付与したクラスではなく、DataStoreSnapshotに準拠した具体型を指定する必 要がある •

    func fetch<T>(_ request: DataStoreFetchRequest<T>) throws -> DataStoreFetchResult<T, DefaultSnapshot> where T : PersistentModel { … } ◦ データストアからデータを取得する処理 • func save(_ request: DataStoreSaveChangesRequest<DefaultSnapshot>) throws -> DataStoreSaveChangesResult<DefaultSnapshot> { … } ◦ データストアにデータを書き込む処理 ◦ insert, update, deleteした時に呼ばれる
  6. JSONStoreConfiguration • typealias Store = JSONStore ◦ DataStoreに準拠している具体型を指定する(今回だと JSONStore) •

    ModelContainerのconfigurationに渡すことでデータストアを指定する ◦ つまり渡すDataStoreConfigurationを変えることで今までのメモリや .storeファイルの保 存先だけでなく、データストアを切り替えることができる
  7. 結果 func fetch<T>(_ request: DataStoreFetchRequest<T>) throws -> DataStoreFetchResult<T, DefaultSnapshot> where

    T : PersistentModel • データを取得するメソッドがasyncじゃない • 取得したデータを戻り値に渡す必要がある ということなのでほぼ無理そう...
  8. 余談 DispatchSemaphore An object that controls access to a resource

    across multiple execution contexts through use of a traditional counting semaphore. 複数の実行コンテキスト間で、従来型のカウントセマフォ を使ってリソースへのアクセスを制御する オブジェクト。(ChatGPT 訳) これを使って非同期処理の完了を同期的に待つことで外部のデータベースをデータストアとして扱い たい
  9. 余談 • サーバー ◦ APIサーバーはHummingbirdを使ってローカルに構築 ◦ データベースSQLiteを使用 • アプリ ◦

    基本的なコードはJSONファイルの時に試したものを流用 ◦ 外部DB用のDataStore、DataStoreConfigurationを追加 ◦ ModelContainerには外部DB用のDataStoreConfigurationを渡す