简体   繁体   English

iCloud Core数据同步设置

[英]iCloud Core Data Sync Setting

I am working on an application that incorporates iCloud syncing of its Core Data store (simple application with a single store/model/context). 我正在开发一个将iCloud与其核心数据存储区进行同步的应用程序(具有单个存储区/模型/上下文的简单应用程序)。 Since the store also contains image data, it has the possibility for getting quite large and so I would like to add a setting to allow the user to disable the syncing if they wish. 由于商店还包含图像数据,因此有可能变得很大,因此我想添加一个设置,以允许用户根据需要禁用同步。 I have looked at some sample code for using Core Data in both scenarios, and it looks to me that the only real difference between running with iCloud enabled and disabled are the options passed to the NSPersistentStoreCoordinator when it is added. 我看了一些在两种情况下都使用Core Data的示例代码,在我看来,启用和禁用iCloud时运行的唯一真正区别是添加时将传递给NSPersistentStoreCoordinator的选项。 As such, I had though about doing something like this: 因此,我不得不这样做:

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
}

So, I have a couple of questions about the above: 因此,我对上述问题有两个疑问:

  1. Is my assumption correct, or is there more between the two states that needs to be different? 我的假设是正确的,还是两个状态之间需要更多不同?
  2. Often in examples this code is called in the application delegate, so it usually is only called once per application run. 通常在示例中,此代码在应用程序委托中被调用,因此通常每个应用程序运行仅被调用一次。 Is there a good strategy to responding to the necessary change on demand as the user toggle the setting? 当用户切换设置时,是否有一个很好的策略来响应必要的按需更改?

Thanks! 谢谢!

This is the solution that I came up with, and it is working pretty well. 这是我想出的解决方案,并且运行良好。 Basically the code below is placed in a method that you can call when your application starts up, or anytime the your user-facing "Enable iCloud Sync" setting changes. 基本上,以下代码位于一种方法中,您可以在应用程序启动时或在面向用户的“启用iCloud Sync”设置发生更改时调用此方法。 All that needs to change between the two operation modes is the NSPersistentStore instance, the underlying model file and the coordinator need no changes. 两种操作模式之间需要更改的全部是NSPersistentStore实例,基础模型文件和协调器无需更改。

My application only has one persistent store to worry about, so upon calling this method, it just removes all stores currently attached to the coordinator, and then creates a new one with the appropriate options based on the user settings. 我的应用程序只需要担心一个持久性存储,因此在调用此方法时,它只删除当前附加到协调器的所有存储,然后根据用户设置使用适当的选项创建一个新存储。

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

If you have an application that utilizes multiple stores, you may need to keep references around to the stores that you want to enable/disable sync on so you can have a smarter approach rather than just blowing them all away every time. 如果您有一个利用多个商店的应用程序,则可能需要保留对要启用/禁用同步的商店的引用,以便您可以采用一种更智能的方法,而不是每次都将其全部销毁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM