i'm having a very hard issue to solve. I've got this scenario:
My app uses CoreData to storing objects, I want to implement iCloud sync between devices... and my app requires an initial populated database.
The first time I launch my app, it's going to populate my database on the cloud and marks to YES some db'fields as "databaseInstalled". These fields are synced in the cloud too.
Now when another device launch the app for the first time, I was hoping to retrieve the field "databaseInstalled" to check whether inject or not some data but it's wrong...
If databaseInstalled is false, we inject data, if databaseInstalled it's true, we wait for iCloud sync.
The problem is that I retrieve the persistentStoreCoordinator asynchronically because of I don't want to block the app that is waiting to download data from iCloud...
So how can I know a priori if i need to populate the database or it has been filled on another device and I've just to download from iCloud the populated one?
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if((__persistentStoreCoordinator != nil)) {
return __persistentStoreCoordinator;
}
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
NSPersistentStoreCoordinator *psc = __persistentStoreCoordinator;
// Set up iCloud in another thread:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// ** Note: if you adapt this code for your own use, you MUST change this variable:
NSString *iCloudEnabledAppID = @"this is a secret!";
// ** Note: if you adapt this code for your own use, you should change this variable:
NSString *dataFileName = @"you do not have to know.sqlite";
// ** Note: For basic usage you shouldn't need to change anything else
NSString *iCloudDataDirectoryName = @"Data.nosync";
NSString *iCloudLogsDirectoryName = @"Logs";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
if (iCloud) {
NSLog(@"iCloud is working");
NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];
NSLog(@"iCloudEnabledAppID = %@",iCloudEnabledAppID);
NSLog(@"dataFileName = %@", dataFileName);
NSLog(@"iCloudDataDirectoryName = %@", iCloudDataDirectoryName);
NSLog(@"iCloudLogsDirectoryName = %@", iCloudLogsDirectoryName);
NSLog(@"iCloud = %@", iCloud);
NSLog(@"iCloudLogsPath = %@", iCloudLogsPath);
// da rimuovere
//[fileManager removeItemAtURL:iCloudLogsPath error:nil];
#warning to remove
if([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) {
NSError *fileSystemError;
[fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]
withIntermediateDirectories:YES
attributes:nil
error:&fileSystemError];
if(fileSystemError != nil) {
NSLog(@"Error creating database directory %@", fileSystemError);
}
}
NSString *iCloudData = [[[iCloud path]
stringByAppendingPathComponent:iCloudDataDirectoryName]
stringByAppendingPathComponent:dataFileName];
//[fileManager removeItemAtPath:iCloudData error:nil];
#warning to remove
NSLog(@"iCloudData = %@", iCloudData);
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
[options setObject:iCloudLogsPath forKey:NSPersistentStoreUbiquitousContentURLKey];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:iCloudData]
options:options
error:nil];
[psc unlock];
}
else {
NSLog(@"iCloud is NOT working - using a local store");
NSLog(@"Local store: %@", localStore.path);
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:localStore
options:options
error:nil];
[psc unlock];
}
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"iCloud routine completed.");
Setup *install = [[Setup alloc] init];
if([install shouldMigrate]) {
HUD = [[MBProgressHUD alloc] initWithView:self.window.rootViewController.view];
HUD.delegate = self;
HUD.labelText = NSLocalizedString(@"Sincronizzazione del database", nil);
[self.window.rootViewController.view addSubview:HUD];
[HUD showWhileExecuting:@selector(installDatabase) onTarget:install withObject:nil animated:YES];
}
else {
[[NSNotificationCenter defaultCenter] postNotificationName:@"setupCompleted" object:self];
}
//[[NSNotificationCenter defaultCenter] postNotificationName:@"icloudCompleted" object:self userInfo:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"setupCompleted" object:self];
});
});
return __persistentStoreCoordinator;
}