0

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
Stefan Kendall
  • 66,414
  • 68
  • 253
  • 406

2 Answers2

2

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.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
0

Your code doesn't indicate this, but you can't call -URLForUbiquityContainerIdentifier on the main thread. Note from the Apple documentation:

Important: Do not call this method from your app’s main thread. Because this method might take a nontrivial amount of time to set up iCloud and return the requested URL, you should always call it from a secondary thread. To determine if iCloud is available, especially at launch time, call the ubiquityIdentityToken method instead.

It could very well be that it takes a long time and that it appears as if your app isn't loading, while in reality it is just waiting for that method to return.

Scott Berrevoets
  • 16,921
  • 6
  • 59
  • 80
  • No. That line returns just fine. It's the addPersistentStore that hangs. – Stefan Kendall Jun 03 '13 at 20:21
  • 1
    I would still try to run it on a different thread. In this SO question someone has the same problem: http://stackoverflow.com/questions/12923238/ios-application-freezing-on-first-launch-when-icloud-is-enabled – Scott Berrevoets Jun 03 '13 at 20:33
  • Good advice that has nothing to do with my problem. Without iCloud *working*, I give 0 shits if there's bugs or it isn't performant. – Stefan Kendall Jun 07 '13 at 15:09
  • Adding `addPersistentStoreWithType:configuration:URL:options:error:` to a different thread didn't help either? – Scott Berrevoets Jun 07 '13 at 18:09