How to access CoreData model in today extension (iOS)

Ben picture Ben · Aug 20, 2014 · Viewed 20k times · Source

Is it possible to work with my CoreData model in the today extension in swift like in the original app? If yes, how can I create the NSManagedObjectContext?
I really have no clue, beside the group-identifier, but unfortunatly I don't know how to get the context..
In the past I created apps with the check at the beginning that I want to use CoreData and then I got the managedObjectContext via my AppDelegate.. But how can I do somethink like that in an extension? Apple doesn't offer information about that..

I edited this line in AppDelegate:

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"HTWcampus.sqlite"];

to this (after including the group to both targets):

NSURL *storeURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.BenchR.TodayExtensionSharingDefaults"];
storeURL = [storeURL URLByAppendingPathComponent:@"HTWcampus.sqlite"];
NSLog(@"StoreURL2: %@", storeURL);

With that the existing database in my app was gone (what is great, because I think it worked to put the database in the shared segment).

But how can I create an instance of my context in the extension? And how can I access my NSManagedObject-subclasses?

In the extension I have this code so far:

var context: NSManagedObjectContext!

override func viewDidLoad() {
    super.viewDidLoad()

    var storeURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.BenchR.TodayExtensionSharingDefaults")
    storeURL = storeURL?.URLByAppendingPathComponent("HTWcampus.sqlite")
    let modelURL = NSBundle.mainBundle().URLForResource("HTWcampus", withExtension: "momd")
    let model = NSManagedObjectModel(contentsOfURL: modelURL)
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
    coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: nil)
    context = NSManagedObjectContext()
    context.persistentStoreCoordinator = coordinator
}

Is this right? And if yes, how can I get my NSManagedObject-Subclasses in there? And do I have to add the momd-file to the extensions target? If yes, how can I do that?

Answer

kkodev picture kkodev · Aug 20, 2014

What you really want is to access your persistent store (most likely a SQLite database). In order to achieve that, you need to configure App Groups and make sure that your host app configures the Core Data stack using your shared container (so your store is accessible in extension as well). Something like:

    NSString *containerPath = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:YOUR_SECURITY_APP_GROUP].path;
    NSString *sqlitePath = [NSString stringWithFormat:@"%@/%@", containerPath, @"database.sqlite"];

Then in your extension just create persistent store coordinator with managed object contexts using database in shared container. You can share your model (.momd) and managed object subclasses with extension just by making sure they are included in extension target as well.

Edit:

To add your model and managed object subclasses:

1. Make sure you have your app and extension targets

  1. Make sure you have your app and extension targets

    2. Click on your model file, and select both targets under 'Target Membership' on right-hand panel

  2. Click on your model file, and select both targets under 'Target Membership' on right-hand panel

    3. Repeat the same with all your managed object subclasses

  3. Repeat the same with all your managed object subclasses