1

Core DataストアのiCloud同期を組み込んだアプリケーション(単一のストア/モデル/コンテキストを持つ単純なアプリケーション)に取り組んでいます。ストアには画像データも含まれているため、かなり大きくなる可能性がありますので、必要に応じて同期を無効にできる設定を追加したいと思います。両方のシナリオでCoreDataを使用するためのサンプルコードをいくつか見てきましたが、iCloudを有効にした場合と無効にした場合の唯一の本当の違いは、NSPersistentStoreCoordinator追加時に渡されるオプションです。そういうものとして、私はこのようなことをすることについて考えていました:

NSPersistentStoreCoordinator *psc;
NSDictionary* options;
//Set options based on iCloud setting
if ([enableSwitch isOn]) {
    options = [NSDictionary dictionaryWithObjectsAndKeys:
        @"<unique name here>", NSPersistentStoreUbiquitousContentNameKey,
        cloudURL, NSPersistentStoreUbiquitousContentURLKey,
        [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
        [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
        nil];
} else {
    options = nil;
}

//Add the coordinator
if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
    //Handle error
}

だから、私は上記についていくつか質問があります:

  1. 私の仮定は正しいですか、それとも異なる必要がある2つの状態の間にもっとありますか?
  2. 多くの場合、このコードはアプリケーションデリゲートで呼び出されるため、通常、アプリケーションの実行ごとに1回だけ呼び出されます。ユーザーが設定を切り替えるときに、必要なオンデマンドの変更に対応するための適切な戦略はありますか?

ありがとう!

4

1 に答える 1

1

これは私が思いついた解決策であり、かなりうまく機能しています。基本的に、以下のコードは、アプリケーションの起動時、またはユーザー向けの「iCloud同期を有効にする」設定が変更されたときに呼び出すことができるメソッドに配置されます。2つの操作モード間で変更する必要があるのはNSPersistentStoreインスタンスだけであり、基になるモデルファイルとコーディネーターを変更する必要はありません。

私のアプリケーションには、心配する永続ストアが1つしかないため、このメソッドを呼び出すと、現在コーディネーターに接続されているすべてのストアが削除され、ユーザー設定に基づいて適切なオプションを使用して新しいストアが作成されます。

NSFileManager *fileManager = [NSFileManager defaultManager];

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"DataModel.sqlite"];
NSError *error = nil;

NSArray *stores = [__persistentStoreCoordinator persistentStores];
for (int i=0; i < [stores count]; i++) {
    [__persistentStoreCoordinator removePersistentStore:[stores objectAtIndex:i] error:&error];
}

//Determine availability.  If nil, service is currently unavailable
NSURL *cloudURL = [fileManager URLForUbiquityContainerIdentifier:nil];
if (!cloudURL) {
    NSLog(@"iCloud currently unavailable.");
}

//Check if user setting has been set
if (![[NSUserDefaults standardUserDefaults] objectForKey:kCloudStorageKey]) {
    //Set the default based on availability
    BOOL defaultValue = (cloudURL == nil) ? NO : YES;
    [[NSUserDefaults standardUserDefaults] setBool:defaultValue forKey:kCloudStorageKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

//Set options based on availability and use settings
BOOL cloudEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:kCloudStorageKey];
NSDictionary *options = nil;

if (cloudEnabled && cloudURL) {
    NSLog(@"Enabling iCloud Sync in Persistent Store");
    options = [NSDictionary dictionaryWithObjectsAndKeys:
            @"<awesome.unique.name.key>", NSPersistentStoreUbiquitousContentNameKey,
            cloudURL, NSPersistentStoreUbiquitousContentURLKey,
            [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
            [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
            nil]; 
}

//Add the store with appropriate options
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
{
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

複数のストアを利用するアプリケーションがある場合は、同期を有効/無効にするストアへの参照を保持して、毎回すべてを吹き飛ばすのではなく、よりスマートなアプローチをとることができるようにする必要があります。

于 2012-07-18T18:18:20.970 に答える