私の問題は、この更新をサーバーに投稿することで、オブジェクトの変更 (関係を含む) のコアデータの認識を調整することです。
例えば:
2 対多の関係を持つマネージド オブジェクトがあるとします。サーバーで get を実行して、両方の関係に含まれるオブジェクトを取得します。関係 A の場合、サーバーは 1 つのオブジェクトが属することを返します。関係 B の場合、サーバーは何も返しません。したがって、A については、JSON 応答を NSManagedObject に解析し、それを関係 A に挿入します。BI については何もしません。この時点で、
-changedValues
rel A の唯一のオブジェクトでクエリを実行すると、rel A に挿入されたため、rel A の逆が変更されたと言えます。サーバーから取得したオブジェクトを表現したいので「デフォルト」または「最後にコミットされた」状態では、コア データ コンテキストの保存を発行します。その時点で、changedValues は挿入を反映しなくなります。ここまでは順調ですね。次に、(サーバーから取得するのではなく) ローカルで 2 つのオブジェクトを作成します。1 つを rel A (現在 2 つのオブジェクト) に挿入し、もう 1 つを rel B (現在 1 つのオブジェクト) に挿入します。
- この時点で、システム全体に、rel A の最初のオブジェクトがそこにあるという事実を認識してもらいたいので、それについて何もする必要はありません。A の 2 番目は新しい挿入であるため、サーバーにポストする必要があり、rel B の唯一のオブジェクトである 3 番目のオブジェクトも新しい挿入であるため、POST が必要です。
適切なリレーションシップの逆にちなんで名付けられたキーに対して -valueChanged の値を持つ適切なリレーションシップ先エンティティのすべてのオブジェクトのコンテキストをクエリすることで、これにアプローチしようとしました。つまり、これらの関係を持つオブジェクト x の場合、現在の状態は次のとおりです。
x.relA = <NSSet: obj1, obj2>
x.relB = <NSSet: obj3>
クエリは本質的に
// For each relationship:
NSError *error = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:mapping.entityName];
NSArray *fetchResult = [self.context executeFetchRequest:fetchRequest error:&error];
NSArray *deletedObjects = [fetchResult filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
id relationship = [evaluatedObject changedValues][<inverseOfRelationship>];
return relationship && ![relationship containsObject:x];
}]];
NSArray *insertedObjects = [fetchResult filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
id relationship = [evaluatedObject changedValues][<inverseOfRelationship>];
return relationship && [relationship containsObject:x];
}]];
これは原則として機能します。しかし、問題は、最初に rel A を評価するとします。削除と挿入のリストを取得し (デフォルトで既に存在していたものはカウントしません)、適切な DELETE と POST をサーバーに発行して、これら 2 つのアレイを処理します。ここまでは順調ですね。ただし、この関係の現在の状態が「デフォルト」状態になるように、coredata コンテキストの保存を発行します。わかった。確かに...しかし...保存により、rel Bのobj3の変更も消去されます。したがって、上記のコードでその関係を照会しようとすると、obj3のchangedValuesは値を報告しません。理論的にはobj3のrelのメンバーシップだからですB がデフォルトです (少なくとも最後の保存以降)。
したがって、一部のオブジェクトに対してのみ選択的なコンテキストの保存を行う方法 (これは「コンテキスト」の保存であり、オブジェクトの保存ではないため、これは不可能だと思います)、またはオブジェクトの changedValues を選択的にクリアする方法が必要です。たとえば、すでにサーバーで処理されています。
もう 1 つのアプローチは、ManagedObjects に追加の更新/削除フラグを挿入し、独自のコードを介して手動で処理することです。実行可能ですが、一種のゲットーのように見えます。これは、基本的に、コンテキストに関連して managedObjects が既に配置されているフラグを転用しているためです。
考えやアイデアはありますか?