オフラインファースト
Amplify DataStore の独自のアプローチについてさらに理解するために、以下のリソースを参照してください。
オフラインファースト アプリケーション構築の原則をさらに探索し理解するために、Android のオフラインファースト アプリケーション構築ガイドを確認することをお勧めします。
これらの機能がアプリケーションにとって重要であることを理解しており、DataStore は新機能を受け取らなくなりますが、スムーズに移行するために必要なリソースを提供したいと考えています。以下のセクションでは、代替ソリューションについての高レベルな推奨事項を示します。
リモート同期
ローカル ストアを定期的に同期することで、アプリケーションのプライマリ ソースとして機能し、オフラインで実行できる読み取り操作を実現できます。オフライン書き込みを管理することを選択すると、アプリケーションに追加の複雑さが生じるため、各個別モデルに対してこれを処理するかどうかを検討することが重要です。
ライブ同期
onCreate、onUpdate、onDelete を使用して Amplify.API.subscribe を活用することで、インターネットに接続している限り、リモート リポジトリへの変更をリアルタイムで検出できます。このメソッドは、サブスクリプションがアプリケーションがオフラインの場合はアクティブにならないため、それ自体では不十分です。
Future<void> initOnlineSync() async { final onCreate = ModelSubscriptions.onCreate(RemoteModel.classType); final createSubscription = Amplify.API.subscribe(onCreate); createSubscription.listen((response) { _syncItem(response, localRepository.create); });
final onUpdate = ModelSubscriptions.onUpdate(RemoteModel.classType); final updateSubscription = Amplify.API.subscribe(onUpdate); updateSubscription.listen((response) { _syncItem(response, localRepository.update); });
final onDelete = ModelSubscriptions.onDelete(RemoteModel.classType); final deleteSubscription = Amplify.API.subscribe(onDelete); deleteSubscription.listen((response) { _syncItem(response, localRepository.delete); });}
Future<void> _syncItem( GraphQLResponse<RemoteModel> response, Function(LocalModel) syncFunction,) async { final remoteModel = response.data; if (remoteModel == null) return;
final localModel = toLocalModel(remoteModel); // Calls localRepository's create, update, or delete method syncFunction.call(localModel);}ローカル キャッシュの更新
アプリケーションがインターネットに再接続するたびに、アプリケーション起動またはネットワーク更新を通じて、ローカル ストアの完全な更新を実行して、見落とした可能性のあるすべての更新を確実に受け取るようにしてください。
Future<void> _syncAll() async { final response = await remoteRepository.readAll(); final remoteItems = response.data?.items; final localData = remoteItems?.nonNulls.map(toLocalModel);
if (localData == null) return;
// Clear local and save results localRepository.rebuild(localData);}ネットワーク ステータスの検出
Amplify.API.mutate 操作が例外をスローするか、サブスクリプション オブザーバーがエラーを送信するのを待つことで、ネットワーク ステータス更新をリアクティブに検出できます。
void _initObservers() { final onCreate = ModelSubscriptions.onCreate(Todo.classType); Amplify.API .subscribe(onCreate) .listen(_syncCreate, onError: (_) => _offlineDetected());
final onUpdate = ModelSubscriptions.onUpdate(Todo.classType); Amplify.API .subscribe(onUpdate) .listen(_syncUpdate, onError: (_) => _offlineDetected());
final onDelete = ModelSubscriptions.onDelete(Todo.classType); Amplify.API .subscribe(onDelete) .listen(_syncDelete, onError: (_) => _offlineDetected());}
Future<GraphQLResponse<Todo>> create(Todo model) async { try { final request = ModelMutations.create(model); return Amplify.API.mutate(request: request).response; } catch (e, st) { _offlineDetected(); rethrow; }}さらに、Amplify Hub を通じてネットワーク ステータス更新をプロアクティブに検出できます。これにより、アクティブなネットワーク リクエストを行っていないにもかかわらず、ローカル キャッシュを同期する必要があるシナリオを特定できます。
Amplify.Hub.listen(HubChannel.Api, _onNetworkStatusChanged);
void _onNetworkStatusChanged(ApiHubEvent hubEvent) { if (hubEvent is SubscriptionHubEvent) { switch (hubEvent.status) { case SubscriptionStatus.connected: _onlineDetected(); break; case SubscriptionStatus.connecting: case SubscriptionStatus.pendingDisconnected: case SubscriptionStatus.disconnected: case SubscriptionStatus.failed: _offlineDetected(); default: break; } }}アプリケーションがオフラインであることを検出したら、ローカル キャッシュの再同期を定期的に試行してください。これにより、アプリケーションがオンラインに戻ったときを検出し、古いデータをクリーンアップできます。バックオフ戦略を実装するか、サードパーティ パッケージを使用して、再同期の試行を効率的に分散することをお勧めします。
Future<void> _offlineDetected() async { if (_isOffline) return; _isOffline = true;
final backoffStrategy = ExponentialJitterBackoff(); while (_isOffline) { await Future.delayed(backoffStrategy.nextDelay());
_isOffline = !await _resync(); }}オフラインミューテーション
ローカルで行われた変更を別のペンディング ミューテーション テーブルに格納し、後で同期することで、ユーザーがオフラインで作業できるようにします。ペンディング ミューテーション テーブルには、以下を含める必要があります。
- 自動インクリメント プライマリ キー(モデルの通常のプライマリ キーではない)
- ミューテーション タイプの列挙(作成、更新、または削除)
- アクション時のモデルの状態
ペンディング ミューテーション テーブルを同期する際には、以下の表に従って Amplify.API.mutate レスポンスを処理してください。
| 例外がスローされた | レスポンスにデータあり | レスポンスにエラーあり | 結果 | アクション |
|---|---|---|---|---|
| TRUE | N/A | N/A | 例外 | 同期を一時停止 |
| FALSE | TRUE | FALSE | 成功 | 同期を続行 |
| FALSE | TRUE | TRUE | 部分的な成功 | 同期を続行 |
| FALSE | FALSE | TRUE | 検証エラー | 同期を続行 |
| FALSE | FALSE | FALSE | 有効な結果ではない | N/A |
ペンディング ミューテーション テーブル エントリを同期する前にアプリに組み込むには、ローカル ストア クエリの結果と集約する必要があります。
同期を手動で開始および停止
DataStore では、データの同期を手動で停止および開始できます。これを実装するには、同期ロジックを実行する前に同期が有効になっているかどうかを確認し、フラグを切り替える方法を提供します。同期を有効にするときは、ローカル ストアを同期することを忘れないでください。
bool _syncEnabled = true;void enableSync() { final previous = _syncEnabled; _syncEnabled = true;
if (previous != _syncEnabled) _syncAll();}
void disableSync() { _syncEnabled = false;}