目前我尝试使用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];
});
}
当前没有使用NSPersistentStoreDidImportUbiquitousContentChangesNotification(我认为只有在其他设备也将一些数据保存到iCloud时才会调用它)
每个应用程序启动时都会调用来自NSPersistentStoreCoordinatorStoresDidChangeNotification的'storeDidChange'。所以目前我不知道我应该在那里做什么。
正如我之前所写,这对我不起作用,如果启用或禁用iCloud,数据将不会合并。
请帮帮我 - 我的想法错了吗?
答案 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)
有两种方法可以做到:
由于代码较少,第二种方式更容易。