Reputation: 16051
I have the following code in my persistentStoreCoordinator. Without the iCloud part, it works fine. With iCloud, it stops on the addPersistentStoreWithType method. No error, it just stops on it and doesn't continue.
Any thoughts?
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [NSURL fileURLWithPath:STORE_PATH];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
NSLog(@"icloud: %@", iCloud);
if (iCloud) {
NSString *iCloudLogsDirectoryName = @"Logs";
NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];
//Create logs directory, in case it doesn't exist
if([fileManager fileExistsAtPath:[iCloudLogsPath path]] == NO) {
NSLog(@"logs directory doesn't exist");
NSError *fileSystemError;
[fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]
withIntermediateDirectories:YES
attributes:nil
error:&fileSystemError];
if(fileSystemError != nil) {
NSLog(@"Error creating logs directory %@", fileSystemError);
}
}
NSString *iCloudEnabledAppID = @"app id removed from stackoverflow";
[options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
[options setObject:iCloudLogsPath forKey:NSPersistentStoreUbiquitousContentURLKey];
NSLog(@"logs path: %@", iCloudLogsPath);
}
[_persistentStoreCoordinator lock];
NSError *error;
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:options
error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
else {
NSLog(@"done adding persistent store");
}
[_persistentStoreCoordinator unlock];
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"SomethingChanged" object:self userInfo:nil];
[self.delegate contextWasSetupInManager:self];
});
});
return _persistentStoreCoordinator;
}
Upvotes: 2
Views: 898
Reputation: 828
I'm not totally sure why these issues come up but I have had a lot of success in getting around problems of this nature by doing a reset of the phone's settings:
Settings > General > Reset > Reset All Settings
Upvotes: 0
Reputation: 2001
I just experienced this on one of my test devices (iPhone 5 running iOS 6.1). Doing a factory reset and then restoring from a current backup of the phone fixed it.
I'm not sure that this is the explanation, but there seems to be an issue with deleting an app's iCloud ubiquity container data through device Settings > iCloud > Storage & Backup. This might put the device into a state where some remnants of the ubiquity container remain and cannot be removed. Doing a full wipe and restore on the device seems to fix it.
I found an old post that looked like it was related this issue (http://stackmonthly.com/2011/11/core-data), and this entry on OpenRadar (http://openradar.appspot.com/10440734). I messed around with it for several hours until I wiped and restored the device, which worked perfectly: the addPersistentStoreWithType completed almost instantly.
Moving forward I'm going to try to clear the store using the nukeAndPave method in the WWDC 2012 sample application SharedCoreData (session 227) rather than manually deleting the store from Settings. Hopefully that will prevent this situation from recurring.
Upvotes: 1
Reputation: 70976
That's common with iCloud. Apple advises you to put it on a background queue since that call may block. It blocks because that's where Core Data actually makes its connection to the iCloud server and starts downloading any new data that's available. The call doesn't continue until it's finished. If there's any significant amount of data to download, you may wait a while.
Sometimes it takes a while for no readily apparent reason. It's flaky like that.
Ultimately what you're seeing is pretty much the way things are with iCloud right now. File a bug or two and hope that things improve.
Upvotes: 2