Search code examples
iosobjective-cicloud

Black screen when attempting to start iCloud app on phone


I have this right now to trigger iCloud loading or not based on whether or not I'm in the simulator. When I try to run on a real device, I get a black screen and the 'addPersistentStore' line seems to hang. "My Project Name" is the name of the entitlements file, and the name of the app.

What's going on?

#if (TARGET_IPHONE_SIMULATOR)
        if (![psc addPersistentStoreWithType:NSSQLiteStoreType
                               configuration:nil
                                         URL:dbUrl
                                     options:nil
                                       error:&error]) {
            [NSException raise:@"Open failed" format:@"Reason: %@", [error localizedDescription]];
        }
#else
        NSFileManager *fm = [NSFileManager defaultManager];
        NSURL *ubContainer = [fm URLForUbiquityContainerIdentifier:nil];
        NSMutableDictionary *options = [NSMutableDictionary dictionary];
        [options setObject:@"My Project Name" forKey:NSPersistentStoreUbiquitousContentNameKey];
        [options setObject:ubContainer forKey:NSPersistentStoreUbiquitousContentURLKey];

        if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:dbUrl options:options error:&error]) {
            [NSException raise:@"Open failed" format:@"%@", [error localizedDescription]];
        }
#endif

Solution

  • Apple recommends that when you're using iCloud, you should do all of these steps on a separate thread. Both URLForUbiquityContainerIdentifier and addPersistentStoreWithType:configuration:options:error: will connect to the network, and may block for long periods. The second call-- adding the persistent store-- can block for a lot longer. On iOS, iCloud data is only downloaded on demand, and this demand happens when you add the persistent store. You're getting a blank screen because NSPersistentStoreCoordinator is busy talking to the network (or trying to do so). Apple's sample code puts this on a separate queue, and you should do this too.