I'm tearing my hair out with this one. I've got an App on iTunes which I added iCloud support to end of last year (Oct '13) on iOS7.0 This week I decided to write a new functional for the App which requires a new entity in the xcdatamodel. A very simple change/addition. Should have no impact on the current data set. I create a new v2 xcdatamodel and set it to Current Model version, compile and run and it works fine if I've got iCloud switch off on my iPad. I see previous saved data. Run it again with iCloud switch on and I get a blank table with no data. No error messages, nothing. Hoping someone can throw some light on what I've done wrong here:
- (NSManagedObjectModel *)managedObjectModel {
if (__managedObjectModel != nil) {
return __managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"UserData" withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
NSError *error = nil;
BOOL success = NO;
if((__persistentStoreCoordinator != nil)) {
return __persistentStoreCoordinator;
}
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
NSPersistentStoreCoordinator *psc = __persistentStoreCoordinator;
NSString *iCloudEnabledAppID = @"C3FUPX46ZG~com~software~App";
NSString *dataFileName = @"UserData.sqlite";
NSString *iCloudDataDirectoryName = @"CoreData.nosync";
NSString *iCloudLogsDirectoryName = @"CoreDataLogs";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
if (iCloud && ([UserDefaults getIsiCloudOn])) {
// This iCloud storage fails to migrate.
NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];
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];
NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES,
NSPersistentStoreUbiquitousContentNameKey : iCloudEnabledAppID,
NSPersistentStoreUbiquitousContentURLKey : iCloudLogsPath
};
success = [psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:iCloudData]
options:options
error:&error];
if (!success) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
} else {
// This local storage migrates automatically just fine.
NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES
};
success = [psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:localStore
options:options
error:&error];
if (!success) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:kCoreDataChangeNotification object:self userInfo:nil];
});
return __persistentStoreCoordinator;
}
UPDATE: Switched on core data debugging & iCloud debugging/logging. Migration works for both local & iCloud. Logs are the same, ending with:
CoreData: annotation: (migration) inferring a mapping model between data models with... CoreData: annotation: (migration) in-place migration completed succeessfully in 0.03 seconds -PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:: CoreData: Ubiquity: mobile~F9AC6EB1 Using local storage: 1
With iCloud storage & debugging on it seems to cause a delay and I briefly see my saved data for about 10seconds when it then disappears. Just before it disappears the debugs spit out:
CoreData: annotation: (migration) inferring a mapping model between data models with... Using local storage: 0
The iCloud logs are enormous which is why I'm not posting them here. From what I can see I have over 400 log files and iCloud seems to be doing some sort of syncing. If I leave the App and iPad open and on for a few hours I still see an empty data set. So it's not a case of waiting for a sync catch up. I'm still at a loss even with the debugs on....