I'm trying to learn how to use iCloud with coredata. My target is to sync a single database file on mac/ios. Both my mac and iOS apps seem to be updating iCloud as I can see it under System Preferences->iCloud->Manage ... There's an app named Unknown which everytime I change something on the ios/mac app is getting bigger and bigger. So that makes me think The apps are storing changes to the cloud. The problem is, I'm not getting the NSPersistentStoreDidImportUbiquitousContentChangesNotification
when i change something on the other platform.
There's my code (mac app):
- (void)persistentStoreDidImportUbiquitousContentChangesNotification:(NSNotification *)notif
{
NSLog(@"%@", notif);
}
- (NSURL *)applicationFilesDirectory
{
NSString *identifier = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *libraryURL = [[[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:identifier];
if(![fileManager fileExistsAtPath:[libraryURL path]])
{
[fileManager createDirectoryAtPath:[libraryURL path] withIntermediateDirectories:YES attributes:nil error:nil];
}
return libraryURL;
}
- (NSManagedObjectModel *)managedObjectModel
{
if (__managedObjectModel)
{
return __managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator)
{
return __persistentStoreCoordinator;
}
NSManagedObjectModel *mom = [self managedObjectModel];
if (!mom)
{
NSLog(@"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd));
return nil;
}
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *applicationFilesDirectory = [self applicationFilesDirectory];
NSError *error = nil;
NSDictionary *properties = [applicationFilesDirectory resourceValuesForKeys:[NSArray arrayWithObject:NSURLIsDirectoryKey] error:&error];
if (!properties)
{
BOOL ok = NO;
if ([error code] == NSFileReadNoSuchFileError)
{
ok = [fileManager createDirectoryAtPath:[applicationFilesDirectory path] withIntermediateDirectories:YES attributes:nil error:&error];
}
if (!ok)
{
[[NSApplication sharedApplication] presentError:error];
return nil;
}
}
else
{
if ([[properties objectForKey:NSURLIsDirectoryKey] boolValue] != YES)
{
NSString *failureDescription = [NSString stringWithFormat:@"Expected a folder to store application data, found a file (%@).", [applicationFilesDirectory path]];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setValue:failureDescription forKey:NSLocalizedDescriptionKey];
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:101 userInfo:dict];
[[NSApplication sharedApplication] presentError:error];
return nil;
}
}
NSString *appBundleID = [[NSBundle mainBundle] bundleIdentifier];
NSURL *storeURL = [applicationFilesDirectory URLByAppendingPathComponent:@"MyApp.sqlite"];
NSURL *cloudURL = [[fileManager URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:@"Database"];
NSPersistentStoreCoordinator *coordinator = [[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom] autorelease];
NSDictionary *optionsDict = [NSDictionary dictionaryWithObjectsAndKeys:appBundleID, NSPersistentStoreUbiquitousContentNameKey, cloudURL, NSPersistentStoreUbiquitousContentURLKey, [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,nil];
if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:optionsDict error:&error])
{
[[NSApplication sharedApplication] presentError:error];
return nil;
}
__persistentStoreCoordinator = [coordinator retain];
return __persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext)
{
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator)
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setValue:@"Failed to initialize the store" forKey:NSLocalizedDescriptionKey];
[dict setValue:@"There was an error building up the data file." forKey:NSLocalizedFailureReasonErrorKey];
NSError *error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
[[NSApplication sharedApplication] presentError:error];
return nil;
}
__managedObjectContext = [[NSManagedObjectContext alloc] init];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(persistentStoreDidImportUbiquitousContentChangesNotification:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:coordinator];
return __managedObjectContext;
}
I faced the same problem with iOS SDK.
To get "NSPersistentStoreDidImportUbiquitousContentChangesNotification" notification, you must call "- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject" from NSNotification center.
I added this line
[[NSNotificationCenter defaultCenter] addObserver:masterViewController selector:@selector(notifyiCloud:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:[self persistentStoreCoordinator]];
in the "didFinishLaunchingWithOptions" method of AppDelegate. In my case, (iOS5) it worked perfectly, but I don't know if it will work in mac os, too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With