1

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.

JeanDujardin
  • 162
  • 1
  • 10
  • https://developer.apple.com/documentation/coredata/linking_data_between_two_core_data_stores – lorem ipsum Feb 16 '22 at 14:35
  • https://stackoverflow.com/questions/71042928/fetch-request-must-have-an-entity-using-fetchrequest-in-swiftui/71042948#71042948 – lorem ipsum Feb 16 '22 at 14:36
  • I don't get how to code this, I only have one single Default configuration in ```MyApp.xcdatamodeld```. And how to retrieve data from of both "containers" separately? – JeanDujardin Feb 16 '22 at 16:12
  • I'm pretty sure that calling `loadPersistentStores` twice like that is wrong. What you should do is create two persistent store descriptions, add both to the `persistentStoreDescriptions` property, and then call `loadPersistentStores` once. – Tom Harrington Feb 16 '22 at 17:35
  • I’m pretty sure too. I’ve looked in the doc and can’t find it written that is why I suggested that first link but the second link is a recent issue and what I think is a bug. I haven’t been able to test it but if two containers do work and the OP uses a manually created fetch request instead of the built in one it might be solved too. – lorem ipsum Feb 16 '22 at 19:12
  • @TomHarrington Please show me how! – JeanDujardin Feb 17 '22 at 01:35
  • Persistent store descriptions are well documented. Take a look and come back if you have more specific questions. – Tom Harrington Feb 17 '22 at 04:16

1 Answers1

1

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.

malhal
  • 26,330
  • 7
  • 115
  • 133