1

I would like to use the UbiquityContainer in order to have an iCloud backup of the coredata. However if I am not logged into the iCloud on the simulator the ubContainer below remains nil.

-(void)addSqliteStoreToPersistentStoreCoordinator:(NSPersistentStoreCoordinator *)psc{
    NSError *error = nil;
    NSFileManager *fm = [NSFileManager defaultManager];
    NSURL *ubContainer = [fm URLForUbiquityContainerIdentifier:nil]; // Why nil???????
    NSURL *storeURL = [ubContainer URLByAppendingPathComponent:@"f11Remote.sqlite"];
    NSMutableDictionary *options = [NSMutableDictionary dictionary];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
    [options setObject:[NSDictionary dictionaryWithObjectsAndKeys:@"FULL", @"synchronous", nil] forKey:NSSQLitePragmasOption];
    [options setObject:@"f11iCloudStore" forKey:NSPersistentStoreUbiquitousContentNameKey];
    [options setValue:ubContainer forKey:NSPersistentStoreUbiquitousContentURLKey];
    sqliteStore = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];
    if (!sqliteStore)
        [NSException raise:@"FTDatastore: Couldn't open the local SQLite database." format:@"Reason: %@", [error localizedDescription]];
}

I was expecting an offline version of it to work in the meanwhile and behave like core data, until the user logs into the iCloud. What can be done?

Houman
  • 64,245
  • 87
  • 278
  • 460
  • 1
    If the user isn't logged in then there is no ubiquity container. That's why it is `nil`. The user could log into one of several possible iClouds account. Each will have its own container. – rmaddy May 27 '15 at 22:15
  • "What can be done?" What can be done about _what_? This works as expected. What's the problem? Okay, it's a horrible architecture: you have to deal with a persistent store in multiple places. But hey, that's iCloud. – matt May 27 '15 at 22:32
  • @rmaddy so I have to rollout a normal coredata container in case the user is logged out and migrate it to iCloud whenever he logs back in? – Houman May 27 '15 at 22:38

1 Answers1

1

You need a fallback store in case the user did not activate iCloud.

NSURL *storeDirectory = [[NSFileManager defaultManager] 
                        URLForUbiquityContainerIdentifier:nil];

Why nil?

If you specify nil for this parameter, this method returns the first container listed in the com.apple.developer.ubiquity-container-identifiers entitlement array.

If the resulting URL is nil, iCloud is likely disabled. You have to provide an alternative URL.

if (!storeDirectory) {
   storeDirectory = [self applicationDocumentsDirectory]; // implement yourself
   NSLog(@"Falling back to local store.");
}
Mundi
  • 79,884
  • 17
  • 117
  • 140
  • Thank you for explaining it so well. +1 I agree with implementing a fallback to local store if iCloud is disabled. However what do I do, if the user has been iCloud and suddenly decides to logout. The local fallback store would be empty, and he won't be seeing his data. Maybe I should always migrate the iCloud data also to a local data store, for cases like this. – Houman May 28 '15 at 08:22