開発中のアプリケーションでは、データを保存するためにsqliteバッキングストアでコアデータを使用しています。私たちのアプリのオブジェクトモデルは複雑です。また、アプリで配信されるデータの総量が大きすぎて、iOS(iPhone/iPad/iPod Touch)アプリのバンドルに収まらない場合もあります。ユーザーは、通常、データのサブセットのみに関心があるため、データオブジェクトのサブセット(〜100 MB)を同梱するようにデータを分割しています。アプリバンドル。当社のユーザーは、iTunesのアプリ内購入による追加コンテンツの支払い後に、サーバーから追加データオブジェクト(サイズが5 MB〜100 MB)をダウンロードすることができます。 (sqliteバッキングストアに存在する)インクリメンタルデータファイルは、バンドルに同梱されているデータと同じxcdatamodelバージョンを使用します。オブジェクトモデルにはゼロの変更があります。インクリメンタルデータファイルは、gzip形式のsqliteファイルとして当社のサーバーからダウンロードされます。インクリメンタルなコンテンツをアプリと共に出荷することで、アプリケーションバンドルを膨らませたくありません。また、(複雑なデータモデルのため)Webサービスでのクエリに頼ることも望まない。 私たちはサーバーからインクリメンタルsqliteデータのダウンロードをテストしました。ダウンロードしたデータストアを、アプリケーションの共有persistentStoreCoordinatorに追加することができました。 2つのiOSコアデータ永続ストアを効率的にマージする方法は何ですか?
{
NSError *error = nil;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:defaultStoreURL options:options error:&error])
{
NSLog(@"Failed with error: %@", [error localizedDescription]);
abort();
}
// Check for the existence of incrementalStore
// Add incrementalStore
if (incrementalStoreExists) {
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:incrementalStoreURL options:options error:&error])
{
NSLog(@"Add of incrementalStore failed with error: %@", [error localizedDescription]);
abort();
}
}
}
しかし、このようにそれをやって2つの問題があります。
- データはdefaultStoreURLから データの末尾に付加incrementalStoreURLから データを表示(NSFetchResultControllerと、例えば)結果をフェッチします。
- 一部のオブジェクトが複製されています。データモデルには、 の読み取り専用データを持つ多くのエンティティがあります。 2番目のpersistentStoreを のpersistentStoreCoordinatorに追加すると、これらは重複してしまいます。
コアデータは、2つの永続ストアのオブジェクトグラフを1つにマージすることが理想的です(データのダウンロード時に2つのストアのデータの間に共有関係はありません)。また、複製オブジェクトを削除したいと考えています。 ウェブを検索したところ、this answerとthis answerなど、私たちがやっているのと同じことをやろうとしている人たちからいくつか質問がありました。我々はMarcus Zarra's blog on importing large data sets in Core Dataを読んだ。しかし、私たちが見た解決策のどれもが私たちのために働いていませんでした。インクリメンタルストアのデータを手動で読み込んでデフォルトのストアに保存することは望ましくありません。これは、これが非常に遅く、電話でエラーが発生しやすいと考えているからです。マージを行うより効率的な方法はありますか?
私たちは、次のように手動移行を実装することで問題を解決しようとしました。しかし、我々はマージを成功させることができませんでした。私たちは、上で参照された回答1と2で提案された解決策については、本当に明確ではありません。 Marcus Zarraのブログでは、私たちのプロジェクトの初めに大規模なデータセットをiOSにインポートしていたいくつかの問題に取り組んでいました。
{
NSError *error = nil;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
NSMigrationManager *migrator = [[NSMigrationManager alloc] initWithSourceModel:__managedObjectModel destinationModel:__managedObjectModel];
if (![migrator migrateStoreFromURL:stateStoreURL
type:NSSQLiteStoreType
options:options
withMappingModel:nil
toDestinationURL:destinationStoreURL
destinationType:NSSQLiteStoreType
destinationOptions:nil
error:&error])
{
NSLog(@"%@", [error userInfo]);
abort();
}
}
答え1の著者は、増分ストアからの彼のデータを読み込み、デフォルトのストアに保存してしまったようです。おそらく、我々は両方の記事1 &で提案されている解決策を誤解しています。2.私たちのデータのサイズによって、私たちは増分データを手動で読み込んでデフォルトの店に再挿入することができません。私の質問は、(同じobjectModelを持つ)2つのpersistentStoresのオブジェクトグラフを1つのpersistentStoreにマージする最も効率的な方法は何ですか?
オブジェクトのグラフに新しいエンティティ属性を追加したりリレーションシップを変更したりすると、自動移行はかなりうまく機能します。自動移行が実行されるので、停止して再開するのに十分な復元力を持つ同じ永続ストアに類似のデータをマージする簡単なソリューションはありますか?
私が彼を必要とするとき、マーカス・ザラはどこですか?私は[NSPersistentStore migratePersistentStore:toURL:options:withType:error]メソッドを使用していくつかの進歩を遂げました。私は、必要な場所にアクセスするために、いくつかのクリーンアップコードが必要です。 – Sunny
私は同じことをしています。あなたはこれまでに思いついたことを投稿できますか?道に迷いました。 – damon
完了!それがあなたのためにどのように判明したか教えてください。 – Sunny