13

I'm developing app and share extension and trying to use core data. But when I'm inserting items in the extension those items only visible in extension but not from container app (e.g I perform NSFetchRequest from app and getting zero items but in app I got >0). I'm using the following code for getting the persistent container:

lazy var persistentContainer: NSPersistentContainer = {

    let container = NSPersistentContainer(name: "appname")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error {

            fatalError("Unresolved error \(error)")
        }
    })
    return container
}()

Also, the target member ship for appname.xcdatamodeld is checked for both app and extension. How to share core data correctly for both container app and extension?

Cœur
  • 37,241
  • 25
  • 195
  • 267
mirt
  • 1,453
  • 1
  • 17
  • 35

1 Answers1

26
 lazy var persistentContainer: NSPersistentContainer = {
    /*
     The persistent container for the application. This implementation
     creates and returns a container, having loaded the store for the
     application to it. This property is optional since there are legitimate
     error conditions that could cause the creation of the store to fail.
     */
    let container = NSPersistentContainer(name: "xx")

    let appName: String = "xx"
    var persistentStoreDescriptions: NSPersistentStoreDescription

    let storeUrl =  FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.xx.xx.container")!.appendingPathComponent("xx.sqlite")


    let description = NSPersistentStoreDescription()
    description.shouldInferMappingModelAutomatically = true
    description.shouldMigrateStoreAutomatically = true
    description.url = storeUrl

    container.persistentStoreDescriptions = [NSPersistentStoreDescription(url:  FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.xxx.xx.container")!.appendingPathComponent("xx.sqlite"))]

    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()
Garrett Cox
  • 703
  • 6
  • 10
  • Essentially what has changed for Swift 3 is that you need to point to the securitygroup as your store url so that they are both being stored to that. (Assuming that you already set up the app group properly in the project capabilities part) – Garrett Cox Jan 18 '17 at 01:51
  • I have saved the persistent store (sqlite file) to a shared app group directory like above. However, I can't figure out how to access the persistent store from within the app extension. All the code I have found uses the app delegate (not available in the extension) from the main app to get the ManagedObjectContext. Could anyone tell me how to do this? – Michael Bremerkamp Apr 17 '17 at 20:18
  • 3
    There is redundant code. The 1 liner `container.persistentStoreDescriptions = ...` will set correctly. The 6 lines above that are redundant. The default is already true for `shouldInferMappingModelAutomatically` and `shouldMigrateStoreAutomatically` anyway. – samwize Sep 22 '18 at 02:41
  • @MichaelBremerkamp I have the same question. Did you manage to do that? – Reckoner Aug 05 '19 at 14:29