オプション: ローカルキャッシング
顧客への迅速で継続的なアクセスを保証するために、Amplify DataStoreはリモートデータのローカルキャッシュ版を採用しています。Amplify DataStoreからの移行中に、不要な複雑さを避けるために、モデルに合わせたローカルストレージソリューションを選択する必要があります。
DataStoreはSQLite APIを直接使用しますが、選択するオプションはキャッシング要件によって異なる可能性があります。
Apolloの正規化されたキャッシュ
Apollo iOSには、SQLiteを正規化されたキャッシュとして使用するオプションが含まれています。正規化されたキャッシュは設定が簡単で、Apolloがキャッシュから以前のクエリを再生して、遅延を改善し、帯域幅消費を削減し、オフライン中にクエリを再生できます。
正規化されたキャッシュのセットアップ手順については、Migrate DataStore to Apollo — ObserveQueryセクションを参照してください。このセクションではキャッシュを活用するwatch()関数について説明しています。
SwiftDataを使用したカスタムキャッシング
キャッシュされたデータへのより豊富なアクセスが必要な高度な使用例については、Apolloが提供するキャッシュの代わりに、または追加として、独自のキャッシング層を使用できます。このアプローチの2つの一般的なフレームワークはSwiftDataとCoreDataです。以下の例ではSwiftDataを使用しています。
ローカルモデル
Model()マクロを使用して、Apollo生成モデルに対応するローカルストレージ用の別のエンティティに注釈を付けることができます:
@Modelclass PostEntity { @Attribute(.unique) var id: String var updatedAt: String var createdAt: String var status: PostEntityStatus? var title: String var rating: Int? var content: String?
init(id: String, updatedAt: String, createdAt: String, status: PostEntityStatus? = nil, title: String, rating: Int? = nil, content: String? = nil) { self.id = id self.updatedAt = updatedAt self.createdAt = createdAt self.status = status self.title = title self.rating = rating self.content = content }}
enum PostEntityStatus: Codable { case active case inactive}その後、ModelContainerを使用してモデルストレージを構成できます:
let container = try ModelContainer(for: PostEntity.self)モデルマッピング
拡張初期化子は、リモートモデルをローカルモデルにマップするのに役立ちます:
extension PostEntity { convenience init(postDetails: PostDetails) { self.init(id: postDetails.id, updatedAt: postDetails.updatedAt ?? "", createdAt: postDetails.createdAt ?? "", status: (postDetails.status == .case(.active)) ? .active : .inactive, title: postDetails.title, rating: postDetails.rating, content: postDetails.content) }}キャッシュの入力
SwiftDataモデルが設定されたら、Apolloクエリの結果をキャッシュに書き込むことでデータを入力できます:
func populate(apolloClient: ApolloClient, context: ModelContext) { var nextToken: String? = nil repeat { let query = GetPostsQuery( nextToken: nextToken.flatMap { .some($0) } ?? .none) apolloClient.fetch(query: query) { result in guard let data = try? result.get().data else { return } if let items = data.listPosts?.items { for item in items { guard let postDetails = item?.fragments.postDetails else { continue } let model = PostEntity(postDetails: postDetails) context.insert(model) try? context.save() } } nextToken = data.listPosts?.nextToken } } while (nextToken != nil)}可観測性
.NSPersistentStoreRemoteChange通知を監視して、永続ストアの変更をリッスンできます。通知オブジェクトにはトランザクションの履歴トークンが含まれており、これを使用してトランザクション履歴を取得および処理できます。