iCloud Core 数据同步设置

Posted

技术标签:

【中文标题】iCloud Core 数据同步设置【英文标题】:iCloud Core Data Sync Setting 【发布时间】:2012-06-23 12:48:43 【问题描述】:

我正在开发一个应用程序,它结合了其核心数据存储的 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】:

这是我想出的解决方案,效果很好。基本上,下面的代码放置在您可以在应用程序启动时调用的方法中,或者在您面向用户的“启用 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();

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

【讨论】:

嗨@Devunwired,谢谢你的分享!但是,如果用户已经在禁用 iCloud 的情况下添加了一些数据,然后她/他再次打开它会怎样?原来的商店会被完全删除吗?商店似乎会回滚到上次启用 iCloud 的版本.. 我没有看到足够的测试数据来确定。据我所知,一旦再次启用 iCloud,服务会注意到事务日志比上次同步的更新日志,它会提取新数据。 感谢您的回复!我试试看! :D

以上是关于iCloud Core 数据同步设置的主要内容,如果未能解决你的问题,请参考以下文章

Core Data iCloud 同步还是其他?

使用 iCloud 在多台设备上同步 Core Data

Core Data 与 Ensembles 的 iCloud 同步

Core-Data 和 iCloud 限制每个实体的项目数 - 潜在的同步问题

如果我使用 Core Data 手动迁移,我以后可以集成 iCloud 同步吗?

iOS Core Data iCloud 同步 - 可选