iOS 7 iCloud& (启用/禁用)核心数据 - 永无止境的故事

时间:2014-03-07 22:52:08

标签: ios7 icloud

目前我尝试使用CoreData建立iCloud。我的应用程序仅基于iOS 7,因此启用iCloud非常容易。基础工作非常好(保存到iCloud)。我现在正在寻找两周以上,但我找不到解决问题的方法。

我的问题: 如果用户在设置中启用/禁用iCloud或更改iCloud帐户,我的应用程序应以两种方式合并更改。 所以这是我的场景:

应用程序启动 - > iCloud已关闭 - >保存数据(本地) - >用户打开iCloud - >本地数据将合并到iCloud

应用程序启动 - > iCloud开启 - >保存数据(iCloud) - >用户关闭iCloud - > iCloud数据将合并到本地

在一些开发人员编写的许多其他线程中,只有一个持久存储具有相同的选项和url就足够了,因为如果iCloud被禁用,iOS 7核心数据会处理自动回退存储,如果可用则触发合并再次。但那对我不起作用。

以下是一些代码段:

- (NSURL*)storeURL{
NSURL* documentsDirectory = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL];
return [documentsDirectory URLByAppendingPathComponent:[NSString stringWithFormat:@"%@.sqlite",coreDataFileName]];
}

- (NSURL*)modelURL{
return [[NSBundle mainBundle] URLForResource:coreDataFileName withExtension:@"momd"];
}

-(NSMutableDictionary*)getICloudPersistentStoreOptions{
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:
 NSInferMappingModelAutomaticallyOption];

//if(self.hasICloudAccountOnDevice & self.iCloudLokalIsAvailable){
[options setObject:@"iCloudStore" forKey:NSPersistentStoreUbiquitousContentNameKey];        
//}
return options;
}


- (NSManagedObjectContext *)managedObjectContext{
if (masterContext != nil){
    return masterContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil){
    masterContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    masterContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
    [masterContext setPersistentStoreCoordinator: coordinator];
}
return masterContext;
}

- (NSManagedObjectModel *)managedObjectModel{
if (managedObjectModel != nil){
    return managedObjectModel;
}
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:self.modelURL];
return managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
if((persistentStoreCoordinator != nil)){
    return persistentStoreCoordinator;
}
[self createPersistentStoreCoordinator];
return persistentStoreCoordinator;
}

-(void)createPersistentStoreCoordinator{
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
NSPersistentStoreCoordinator *psc = persistentStoreCoordinator;

// iCloud notification subscriptions
NSNotificationCenter *dc = [NSNotificationCenter defaultCenter];
[dc addObserver:self
       selector:@selector(storesWillChange:)
           name:NSPersistentStoreCoordinatorStoresWillChangeNotification
         object:psc];

[dc addObserver:self
       selector:@selector(storesDidChange:)
           name:NSPersistentStoreCoordinatorStoresDidChangeNotification
         object:psc];

[dc addObserver:self
       selector:@selector(persistentStoreDidImportUbiquitousContentChanges:)
           name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
         object:psc];

// Set up iCloud persistent store in another thread:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSError* error;
    [psc lock];
    [psc addPersistentStoreWithType:NSSQLiteStoreType
                      configuration:nil
                                URL:self.storeURL
                            options:[self getICloudPersistentStoreOptions]
                              error:&error];
    [psc unlock];
});
}
在'storeWillChange'方法中我想在NSPersistentStoreUbiquitousTransitionTypeInitialImportCompleted之后实现一些重复数据删除代码,但那是另一回事。

当前没有使用NSPersistentStoreDidImportUbiquitousContentChangesNotification(我认为只有在其他设备也将一些数据保存到iCloud时才会调用它)

每个应用程序启动时都会调用来自NSPersistentStoreCoordinatorStoresDidChangeNotification的'storeDidChange'。所以目前我不知道我应该在那里做什么。

正如我之前所写,这对我不起作用,如果启用或禁用iCloud,数据将不会合并。

请帮帮我 - 我的想法错了吗?

2 个答案:

答案 0 :(得分:2)

看看这里,我就这些问题做了一些笔记。 http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/sample-apps-explanations/

另请查看处理iCloud帐户转换的示例应用程序,我认为您可以在需要转换且目标存储已存在时选择合并选项。

请注意,如果用户在ICloud为ON时选择使用本地存储,则会删除iCloud存储。也不是说在iCloud关闭后没有尝试迁移iCloud存储。根据Apple的说法,一旦用户退出iCloud,您就无法依赖iCloud存储。

答案 1 :(得分:0)

有两种方法可以做到:

  1. 从一个商店向另一个商店深度复制实体;
  2. 将商店从本地迁移到iCloud,反之亦然。
  3. 由于代码较少,第二种方式更容易。