38

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?

Kampai
  • 22,848
  • 21
  • 95
  • 95
Ben
  • 3,455
  • 3
  • 26
  • 31

1 Answers1

69

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

Community
  • 1
  • 1
kkodev
  • 2,557
  • 23
  • 23
  • How can I include the model (momd) in the target? I don't even see it in the apps target – Ben Aug 20 '14 at 15:35
  • I really would like to mark your answer as the right answer, could you please be a little bit more precisely? – Ben Aug 21 '14 at 07:45
  • Thanks for the great pictures! In the code I get the model with NSBundle.mainBundle().URLForResource("HTWcampus", withExtension: "momd") in the extension right? – Ben Aug 21 '14 at 10:56
  • 7
    @KamilKocemba this looks and works fine but how will be the locking work when the extension and the app both will try and read/write on the same physical file. – Ravi Dalmia Mar 20 '15 at 11:20
  • Thanks! You can also read how to configure `App Groups` in this article: https://www.invasivecode.com/weblog/sharing-data-between-apps-and-their-extenstions/ – Lion Sep 05 '15 at 12:36
  • @RaviDalmia Did you give it a try? I was planning to include an app extension to provide data synchronization to an existing app. Did you find any problems with locks and/or read/write issues? – Saul Martínez May 18 '16 at 18:51
  • @SaulMartínez initially we tried doing with with multiple approaches Baton passing or saving Object IDs of changed objects but eventually we removed all that and were only reading in an extension and read write from the app due to a functional change. – Ravi Dalmia May 19 '16 at 06:23
  • @RaviDalmia Thank for your answer, Ravi. We're having issues working with Core Data in background threads to synchronize using AFNetworking, and thought that we would be better off using an app extension, then started to think about SQLite locks and just went crazy... I'll give http://realm.io a try. – Saul Martínez May 20 '16 at 07:09
  • Is there any possible way to create a sample code based on your answer ? swift would be great ! or please answer my Q :http://stackoverflow.com/questions/38592662/using-core-data-in-watch-os-and-today-extension/38592750#38592750 – iOS.Lover Jul 26 '16 at 15:43
  • @kkodev: can't we just pass the NSManagedObjectContext to the extension from the container app via the App Groups? – valeCocoa Aug 28 '17 at 15:01