我正在尝试使用iCloud在设备之间同步Core Data(使用新的iOS7方法)。在使用模拟器进行测试时,我仍然看到同步问题。有时来自一个模拟器的数据不会同步到另一个模拟器。什么可能是问题?以下是AppDelegate.m的大部分代码:
NSManagedObjectContext *context = [self managedObjectContext];
if (!context)
[self displayAlert];
rvc.managedObjectContext = context;
#pragma mark -
#pragma mark Core Data stack
/**
Returns the managed object context for the application.
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
*/
- (NSManagedObjectContext *)managedObjectContext {
if (__managedObjectContext != nil) {
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
NSManagedObjectContext* moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc performBlockAndWait:^{
[moc setPersistentStoreCoordinator: coordinator];
if(!isOldVersion){
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(mergeChangesFrom_iCloud:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:coordinator];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(storesWillChange:) name:NSPersistentStoreCoordinatorStoresWillChangeNotification object:coordinator];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(storesDidChange:) name:NSPersistentStoreCoordinatorStoresDidChangeNotification object:coordinator];
[moc setMergePolicy:[[NSMergePolicy alloc] initWithMergeType:NSMergeByPropertyObjectTrumpMergePolicy]];
}
}];
__managedObjectContext = moc;
}
return __managedObjectContext;
}
- (void)storesWillChange:(NSNotification *)notification {
if (__managedObjectContext) {
[__managedObjectContext performBlockAndWait:^{
if ([__managedObjectContext hasChanges]) {
NSError *error = nil;
[__managedObjectContext save:&error];
}
[__managedObjectContext reset];
}];
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"SCEmptyClips" object:self userInfo:nil];
});
}
}
-(void)storesDidChange:(NSNotification *)n{
[[NSNotificationCenter defaultCenter] postNotificationName:@"SCDataChange" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:@"SCPBUpdateCheck"]];
}
/**
Returns the managed object model for the application.
If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
*/
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
return managedObjectModel;
}
/**
Returns the persistent store coordinator for the application.
If the coordinator doesn't already exist, it is created and the application's store added to it.
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil){
return __persistentStoreCoordinator;
}
firstPost = NO;
NSLog(@"STARTING to configure iCloud / new persistent store");
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"SmartCopy.sqlite"]];
NSDictionary *options;
if(!isOldVersion && [[userDefaults valueForKey:@"SCiCloudMode"] boolValue]){
options = @{NSPersistentStoreUbiquitousContentNameKey: @"MYStoreName"};
}else if(!isOldVersion){
options = @{NSPersistentStoreRemoveUbiquitousMetadataOption: @YES};
}else{
options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
}
[__persistentStoreCoordinator lock];
result = [__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:nil];
if (!result)
[self displayAlert];
[__persistentStoreCoordinator unlock];
NSLog(@"Persistent store added. Now **%u** store(s)", [[[self persistentStoreCoordinator] persistentStores] count]);
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"SCDataChange" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"SCPBUpdateCheck"]];
firstPost = YES;
});
return __persistentStoreCoordinator;
}
- (void)mergeChangesFrom_iCloud:(NSNotification *)notification {
NSLog(@"iCloud actual import");
NSLog(@"insert %@", [[notification userInfo] valueForKey:@"inserted"]);
NSLog(@"delete %@", [[notification userInfo] valueForKey:@"deleted"]);
NSLog(@"update %@", [[notification userInfo] valueForKey:@"updated"]);
[__managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
[[NSNotificationCenter defaultCenter] postNotificationName:@"SCDataChange" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:@"SCPBUpdateCheck"]];
}
#pragma mark -
#pragma mark Application's documents directory
/**
Returns the path to the application's documents directory.
*/
- (NSString *)applicationDocumentsDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
有什么问题吗?
答案 0 :(得分:4)
我是这样做的。这可能是简化和整理代码的简单方法。
self.managedObjectContext = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSMainQueueConcurrencyType];
self.managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
self.managedObjectContext.persistentStoreCoordinator =
[[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:self.managedObjectModel];
[self.managedObjectContext.persistentStoreCoordinator
addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.storeURL
options:@{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore" }
error:&error];
唯一的iCloud位是options参数。 (为清楚起见,我删除了其他选项。)商店网址只有[documentsDirectory URLByAppendingPathComponent:@"Store.sqlite"]
。
我也在听这些:
NSPersistentStoreDidImportUbiquitousContentChangesNotification
NSPersistentStoreCoordinatorStoresWillChangeNotification
NSPersistentStoreCoordinatorStoresDidChangeNotification
在第一个中,我打电话给
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:note];
并发布另一个通知来更新UI;在第二个,我救;在第三个我也更新了UI。
对我来说,真的就是它。它到目前为止完美无瑕。
信用转到iCloudCoreDataStack。