問題文
同じ PersistentStoreCoordinator に割り当てられた 2 つの SQLite ストアの 1 つである読み取り/書き込みストアにレコードを保存しようとすると、iPhone アプリがクラッシュします。レコードを保存する際の明らかな問題の 1 つは、PersistentStoreCoordinator がデータを保存するストアを認識していないことです (これを実現する方法がわからないためです)。
まず、全体像を示して、私のアプローチが適切であることを確認します。次に、実装の詳細を提供します。
バックグラウンド
これは、私が取り組んでいる実際のアプリの重要な側面を表す簡単な例です。

シードデータ

ユーザー入力シナリオ

現在の実装
コアデータの実装

データの保存と検索

もちろん、選択リストを参照して属性を選択するときに、その選択が 2 つの異なるストアからのものであるという証拠をユーザーに与えるべきではありません。
永続ストア コーディネーターのセットアップ
- (NSPersistentStoreCoordinator*)persistentStoreCoordinator {
if (_persistentStoreCoordinator == nil) {
NSArray *bundles = @[[NSBundle bundleForClass:[self class]]];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:bundles]];
NSError *error;
//--------------------------------------------------
// Set options for the USER DATA Persistent Store.
NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES};
//--------------------------------------------------
// Add the USER DATA Store to the Persistent Store Coordinator.
NSPersistentStore *persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.persistentStorePathForUserData
options:options
error:&error];
//--------------------------------------------------
// Set options for the SEED DATA Persistent Store.
options = @{NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES,
NSReadOnlyPersistentStoreOption : @YES};
//--------------------------------------------------
// Add the SEED DATA Store to the Persistent Store Coordinator.
persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.persistentStorePathForSeedData
options:options
error:&error];
}
return _persistentStoreCoordinator;
}
重要な目標
次の点に注意してください。
- 可能であれば、舞台裏でデータのバージョンを管理する必要なしにシード データの更新を行うことを希望します (つまり、新しいまたは変更されたシード データ レコードのみをアプリの更新で提供し、何らかの方法で削除を処理する)、バージョン チェック機能を実装する必要があります。ユーザーがバージョン n から n+5 にアップグレードする状況を処理するコード。
- ユーザー データとシード データには、2 つの間で重複するレコードを含めてはならず、同じ ManagedObjectModel を使用する必要があります。したがって、データとモデルの観点から、2 つのストアをマージしたり、1 つのストアを別のストアに移行したりする必要はありません。
リサーチ
この場合、 複数のストアから単一の永続ストアにオブジェクトを保存すると、2 つのストアがマージされ、すべてのレコードがフェッチされ、重複が除外され、コンテキストが保存されます。何千ものレコードをマージして重複をチェックする必要がないことを望んでいます。(上記の重要な目標 #2 を参照してください。)
この場合、 2 つの iOS Core Data Persistent Store をマージする効率的な方法は何ですか? 、特定のエンティティは読み取り専用で、その他は読み取り/書き込み可能です。私のアプリでは、シード データ ストア内のすべてのエンティティは読み取り専用であり、ユーザー データ ストア内の同じエンティティは読み取り/書き込みです。したがって、移行は適用できないと思います。(上記の重要な目標 #2 を参照してください。)
Apple のCore Data Programming Guideの「Persistent Store Coordinator」の下にある図 4「高度な永続化スタック」は、2 つの Store を使用する Core Data の実装を示していますが、ここでも、各 Store は個別の異なるオブジェクトで構成されています。私のアプリでは、各オブジェクトが各 Store に表示されます。
ここで提案されている解決策 Combining Two SQLite Stores Into Oneは、異なるストア内のオブジェクト間に関係のない 2 つのストアを持つことに関連しているように見えますが、私が実装したものと比較するための詳細は提供されていません。
私はMarcus Zarra による Core Data (2nd Edition)の最初の 3 つの章を読みましたが、彼は移行を必要としない 2 つのストアの使用には取り掛かりませんでした。ただし、第 3 章では、バージョン管理の非常に明確な例を示しています。(複雑なので、上記の重要な目標 #1 にたどり着きました。)
このソリューション ( Which persistent store is used by default by core data in iPhone ) は、ManagedObjectModel の複数の構成を使用することを提案していますが、各エンティティは 1 つの構成にのみ割り当てられます。この解決策が私の状況にどのように推定できるか、あるいは推定できるかどうかさえわかりません。
ここで提案されている解決策は、2 種類の永続ストアを持つ NSPersistentStoreCoordinator でしょうか。、私が必要とするものに近いです。残念ながら、リクエストのみが処理されます。保存用のクラス NSManagedObjectContext に、NSFetchRequest メソッド setAffectedStores に類似したメソッドがありません。


