ios - iCloud 核心数据同步设置

标签 ios core-data icloud

我正在开发一个应用程序,该应用程序结合了 iCloud 同步其核心数据存储(具有单个存储/模型/上下文的简单应用程序)。由于商店还包含图像数据,它有可能变得非常大,所以我想添加一个设置以允许用户根据需要禁用同步。我查看了在这两种情况下使用 Core Data 的一些示例代码,在我看来,启用和禁用 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. 通常在示例中,此代码在应用程序委托(delegate)中调用,因此每次应用程序运行通常只调用一次。当用户切换设置时,是否有一个好的策略来响应必要的更改?

谢谢!

最佳答案

这是我想出的解决方案,而且效果很好。基本上,下面的代码放在一个方法中,您可以在应用程序启动时调用该方法,或者在面向用户的“启用 iCloud 同步”设置更改时随时调用。两种操作模式之间需要改变的只是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();
}

如果您有一个使用多个商店的应用程序,您可能需要保留对要启用/禁用同步的商店的引用,以便您可以采用更智能的方法,而不是每次都将它们全部清除。

关于ios - iCloud 核心数据同步设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11169627/

相关文章:

iphone - 如何保证核心数据实体的单一实例

ios - 如何使用 Cordova 获取 iOS 用户设置的设备名称?

Iphone - App ID 和应用内购买

ios - 定义 UIViewController 或 UIView 的自定义框架

objective-c - 将非持久变量添加到 nsmangedobject

javascript - html input type=file -- 从 iCloud 选择一个文件

ios - Swift 和 CoreData,关系问题 (NSSet) - [NSSet intersectsSet :]: set argument is not an NSSet

objective-c - 与一个实体有多种关系而没有反向?

ios - 是否可以在“设置”->“iCloud”->“文档和数据”中拦截 iCloud 打开/关闭?

ios - 在 iOS 应用程序中检索文本文件