CoreData - load local and AppGroup NSPersistentContainers

243 Views Asked by At

I want to load both the local's NSPersistentContainer and the AppGroup's NSPersistentContainer

Here is what I did :

class MyAppGroupPersistentContainer: NSPersistentContainer{
    override class func defaultDirectoryURL() -> URL{
        return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.myDomain.myApp")!
    }   
}
struct PersistenceController {
    static let shared = PersistenceController()
    
    let containerLocal: NSPersistentContainer
    let containerAppGroup: NSPersistentContainer

    init() {
        let a = NSPersistentContainer(name: "MyApp")
        a.loadPersistentStores(completionHandler: {(x, y) in})

        let b = MyAppGroupPersistentContainer(name: "MyApp")
        b.loadPersistentStores(completionHandler: {(x, y) in})

        self.containerLocal = a
        self.containerAppGroup = b
}

But then, if I execute this code when I click on a SwiftUI button :

let allA = try! PersistenceController.shared.containerLocal.viewContext.fetch(GameData.fetchRequest())
let allB = try! PersistenceController.shared.containerAppGroup.viewContext.fetch(GameData.fetchRequest())
print(allA.count)
print(allB.count)

It crashes with Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'executeFetchRequest:error: A fetch request must have an entity.'

But if I remove all the code related to containerAppGroup OR containerLocal the error disappears and everything is ok. But in this case I cannot access to both containers data while my app is running.

1

There are 1 best solutions below

2
On

You need to load the 2 stores into 1 container. This is because we can only have one viewContext. There are methods available to choose what stores are used when querying or saving, see affectedStores. You can also use configurations in the model editor to choose what entities are in each store.