0

Trying to use CoreData in Keyboard Extension. I guess that database file must be in one place for both - extension and containing app. That place is app group. I made it in Apple account. I set using it in both app and extension (checkbox in Singing and Capabilities). But it s not the same in app and extension or I misunderstood something. Here`s some code.

In my app I made a lazy var to store DB file URL in AppDelegate file:

   lazy var secureAppGroupPersistentStoreURL : URL = {
       let fileManager = FileManager.default
       let groupDirectory = fileManager.containerURL(forSecurityApplicationGroupIdentifier: "group.xxxxx")!
       //xxxxx - is my real bundle identificator
       return groupDirectory.appendingPathComponent("SharedData.sqlite")
    }()

I think it must pointing to file in shared folder. Then I create PersistentContaner like this

   lazy var testPersistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "testDataShare")
        let description = NSPersistentStoreDescription(url: secureAppGroupPersistentStoreURL)
        description.shouldInferMappingModelAutomatically = true
        description.shouldMigrateStoreAutomatically = true
        container.persistentStoreDescriptions = [description]

        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

I using NSPersistentStoreDescription to set DB filename. At least I believe it works so:) After that in my SceneDelegate file I use this container like this (my test entity is called Entity and has only one attribute called name):

//debug
    let testContext = (UIApplication.shared.delegate as! AppDelegate).testPersistentContainer.viewContext
    let fetchRequest: NSFetchRequest<Entity> = Entity.fetchRequest()
     if let keyboards = try? testContext.fetch(fetchRequest){
         print("fetch: \(keyboards.debugDescription)")
     }else{
         print("fetched nothin")
     }

    let testEntity = Entity(context: testContext)
    testEntity.name = "test from app"
    _ = try? testContext.save()

just for testing I insert one more object every time I start my app. It works fine for now. I getting debug info in console like this:

fetch: [ (entity: Entity; id: 0x9f53fc35e433bbae ; data: ), (entity: Entity; id: 0x9f53fc35e43fbbae ; data: ), (entity: Entity; id: 0x9f53fc35e43bbbae ; data: ), (entity: Entity; id: 0x9f53fc35e427bbae ; data: ), (entity: Entity; id: 0x9f53fc35e423bbae ; data: ), (entity: Entity; id: 0x9f53fc35e42fbbae ; data: ), (entity: Entity; id: 0x9f53fc35e42bbbae ; data: { name = "test from app"; })]

I did the very same in my extension, added lazy var secureAppGroupPersistentStoreURL, created PersistentContainer to KeyboardViewController and trying to do the same fetch in viewDidLoad() but its doesn't show any results.

override func viewDidLoad() {
    super.viewDidLoad()


    let context = self.testPersistentContainer.viewContext
    let fetchRequest: NSFetchRequest<Entity> = Entity.fetchRequest()
    if let keyboards = try? context.fetch(fetchRequest){
        print("fetch: \(keyboards.debugDescription)")
    }else{
        print("fetched nothin")
    }
    //...
}

When I starts extension simulation it prints this:

2020-03-06 01:17:25.835412+0300 Keyboard[3482:275851] Failed to inherit CoreMedia permissions from 3042: (null) fetch: []

I expect the objects I saved in app will be able to fetch in extension and vice versa.

What am I doing wrong with database file?

Aspid
  • 629
  • 6
  • 20
  • 1
    Does your keyboard extension has enabled full access ? If no, I am afraid you cannot access shared data, even save to UserDefaults between extensions and parent app. – ares777 Apr 22 '20 at 10:40
  • @user3344236 yes it does. I know that I need it to share data. – Aspid Apr 23 '20 at 12:32
  • oh yes! It was stupid but I forget to check full access again after selecting another device for simulation (or I reset simulation, not really sure how exactly I lost it). I was really sure it is on, but it wasn't. After I turned it on, I got my entities fetched. Post it like an answer and I'll give you a bounty. – Aspid Apr 23 '20 at 12:40
  • by the way, I still getting message: Failed to inherit CoreMedia permissions from 23131: (null) Don't you know what is it? – Aspid Apr 23 '20 at 12:52
  • Check https://stackoverflow.com/questions/26091463/today-extension-failed-to-inherit-coremedia-permissions-from it is obvious related to App Groups entity – ares777 Apr 28 '20 at 06:44

1 Answers1

0

Make sure your keyboard extension has enabled full access. If no, I am afraid you cannot access shared data, even save to UserDefaults between extensions and parent app.

ares777
  • 3,590
  • 1
  • 22
  • 23