Search code examples
objective-cmacosnsmanagedobjectcontextxcode8

NSPersistentContainer fails without error


I'm suddenly beset by Core Data problems in the form of managedObjectContexts that are nil two-thirds of the time: the onset more or less coincides with upgrading to Xcode 8. The new NSPersistentContainer class seemed to offer an opportunity to solve my problems and get rid of some ugly code. Unfortunately, I cannot make it work.

In AppDelegate.h

@property (readonly, strong, nonatomic) NSPersistentContainer *persistentContainer;

In AppDelegate.m:

@synthesize persistentContainer = _persistentContainer;
- (NSPersistentContainer *)persistentContainer
{
    if (!_persistentContainer) {
        _persistentContainer = [NSPersistentContainer persistentContainerWithName:@"I_WILL_PERSIST"];
        __block BOOL storesWereLoaded = NO;
        [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *psd, NSError *error) {
            if (error) {
                NSLog(@"loadPersistentStoresWithCompletionHandler: persistent container could not load store %@. Error: %@",
                      psd, error.debugDescription);
            } else {
                storesWereLoaded = YES;
            }
        }];
        if (storesWereLoaded) {
            NSLog(@"Stores were loaded");
        } else {
            NSLog(@"Stores were not loaded");
        }
    }
    return _persistentContainer;
}

The app is a little test app, with an arrayController bound (in IB) to App Delegate.persistentContainer.viewContext. App Delegate is connected and not nil. The persistentContainer getter is called repeatedly but the NSLog's inside the block never fire and the console shows:

Cannot perform operation without a managed object context 2016-09-24 19:34:39.207 I_WILL_PERSIST[5588:180829] ( 0 CoreFoundation
0x00007fff8da994f2 __exceptionPreprocess + 178 1 libobjc.A.dylib
0x00007fff8ed6173c objc_exception_throw + 48 2 CoreFoundation
0x00007fff8db004bd +[NSException raise:format:] + 205 3 AppKit
0x00007fff85d411c4 -[_NSManagedProxy _managedObjectContext] + 66

Does the problem lie in my shaky block-programming skills? Is it a signing / permissions issue (the app is not Sandboxed, code signing automatic)? What's with Core Data all of a sudden?

====EDIT==== After upgrading to Mac OS 10.12 (Sierra), NSPersistentContainer fails with error:

2016-09-28 20:55:53.256588 osPersist[1936:41151] [error] error:
-addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Users/user/Library/Application%20Support/osPersist/osPersist.sqlite options:{
    NSInferMappingModelAutomaticallyOption = 1;
    NSMigratePersistentStoresAutomaticallyOption = 1; } ... returned error Error Domain=NSCocoaErrorDomain Code=512 "The file couldn’t be saved." UserInfo={reason=Failed to create file; code = 2} with userInfo dictionary {
    reason = "Failed to create file; code = 2"; } 2016-09-28 20:55:53.256747 osPersist[1936:41151] Unresolved error Error Domain=NSCocoaErrorDomain Code=512 "The file couldn’t be saved." UserInfo={reason=Failed to create file; code = 2}, {
    reason = "Failed to create file; code = 2"; }

Why the database creation fails is not clear: it happens both with and without code-signing. I've made a bug report and I've opened a support request.


Solution

  • As soon as I upgraded to Sierra (MacOS 10.12) NSPersistentContainer started failing with errors. So, you can implement NSPersistentContainer in Xcode 8 running on MacOS 10.11 and your project will compile and run, but NSPersistentContainer won't do squat. I've filed a bug report and I hope that Apple will add preprocessor directives to the class, but they don't seem very interested.