2012-06-23 183 views
1

我正在開發一個應用程序,該應用程序結合了其Core Data存儲(簡單應用程序與單個商店/模型/上下文)的iCloud同步。由於商店還包含圖片數據,因此它有可能變得非常大,所以我想添加一個設置以允許用戶在他們希望的情況下禁用同步。我已經查看了在兩種情況下使用Core Data的一些示例代碼,並且在我看來,在啓用和禁用iCloud的情況下運行的唯一真正區別在於添加時傳遞到NSPersistentStoreCoordinator的選項。因此,我雖然這樣做這樣的事情:iCloud核心數據同步設置

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. 通常在示例中,此代碼在應用程序委託中調用,所以通常只在每次應用程序運行時調用一次。在用戶切換設置時,是否有一個很好的策略來響應需求中的必要更改?

謝謝!

回答

1

這是我提出的解決方案,它工作得很好。基本上,下面的代碼放置在一個方法中,您可以在應用程序啓動時或在任何時候面向用戶的「啓用iCloud Sync」設置更改時調用該方法。所有需要在兩種操作模式之間切換的是NSPersistentStore實例,底層模型文件和協調器無需更改。

我的應用程序只有一個需要擔心的持久存儲,因此在調用此方法時,它只會刪除當前連接到協調器的所有存儲,然後根據用戶設置使用適當的選項創建一個新存儲。

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(); 
} 

如果您有利用多個商店的應用程序,你可能需要保持周圍的引用要啓用/禁用同步商店上,所以你可以有一個更聰明的方法,而不是隻吹他們全部帶走每次。

+0

嗨@Devunwired,謝謝您的分享!但是如果用戶在iCloud禁用時已經添加了一些數據,然後再次打開它,該怎麼辦?原始商店將被完全刪除嗎?似乎該商店將回滾到最後一次啓用iCloud的版本。 – Kjuly

+0

我還沒有看到足夠的測試數據以確認。據我所知,一旦iCloud再次啓用,服務注意到事務日誌比上次同步的事務日誌更新,並且它提取新數據。 – Devunwired

+0

謝謝您的回覆!我會試一試! :d – Kjuly