CoreData в расширении: как использовать базу данных в общей группе

Пытаюсь использовать CoreData в расширении клавиатуры. Я предполагаю, что файл базы данных должен быть в одном месте как для расширения, так и для содержащего приложения. Это место — группа приложений. Я сделал это в аккаунте Apple. Я установил его использование как в приложении, так и в расширении (флажок в Singing and Capabilities). Но это не то же самое в приложении и расширении, или я что-то не так понял. Вот некоторый код.

В моем приложении я сделал ленивую переменную для хранения DB файла URL в файле AppDelegate:

   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")
    }()

Я думаю, что он должен указывать на файл в общей папке. Затем я создаю PersistentContaner вот так

   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
    }()

Я использую NSPersistentStoreDescription для установки имени файла БД. По крайней мере, я считаю, что это работает так:) После этого в моем файле SceneDelegate я использую этот контейнер следующим образом (моя тестовая сущность называется Entity и имеет только один атрибут с именем 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()

просто для тестирования я вставляю еще один объект каждый раз, когда запускаю свое приложение. На данный момент это работает нормально. Я получаю отладочную информацию в консоли следующим образом:

выборка: [ (сущность: сущность; идентификатор: 0x9f53fc35e433bbae; данные:), (сущность: сущность; идентификатор: 0x9f53fc35e43fbbae; данные:), (сущность: сущность; идентификатор: 0x9f53fc35e43bbbae; данные: ), (сущность: сущность; идентификатор: 0x9f57fc35e42ae ; data: ), (entity: Entity; id: 0x9f53fc35e423bbae; data: ), (entity: Entity; id: 0x9f53fc35e42fbbae; data: ), (entity: Entity; id: 0x9f53fc35e42bbbae; data: { name = "test from app" ; })]

Я сделал то же самое в своем расширении, добавил ленивую переменную secureAppGroupPersistentStoreURL, создал PersistentContainer в KeyboardViewController и попытался сделать ту же выборку в viewDidLoad(), но это не показывает никаких результатов.

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")
    }
    //...
}

Когда я запускаю симуляцию расширения, он печатает это:

06.03.2020 01:17:25.835412+0300 Клавиатура[3482:275851] Не удалось наследовать разрешения CoreMedia от 3042: (null) fetch: []

Я ожидаю, что объекты, которые я сохранил в приложении, смогут получить расширение и наоборот.

Что я делаю не так с файлом базы данных?


person Aspid    schedule 05.03.2020    source источник
comment
Ваше расширение клавиатуры включило полный доступ? Если нет, я боюсь, что вы не можете получить доступ к общим данным, даже сохранить в UserDefaults между расширениями и родительским приложением.   -  person ares777    schedule 22.04.2020
comment
@user3344236 user3344236 да, это так. Я знаю, что мне это нужно для обмена данными.   -  person Aspid    schedule 23.04.2020
comment
о, да! Это было глупо, но я забываю снова проверить полный доступ после выбора другого устройства для симуляции (или я сбрасываю симуляцию, не совсем уверен, как именно я ее потерял). Я был уверен, что он включен, но это не так. После того, как я включил его, я получил свои сущности. Разместите это как ответ, и я дам вам награду.   -  person Aspid    schedule 23.04.2020
comment
кстати, я все еще получаю сообщение: Не удалось наследовать разрешения CoreMedia от 23131: (ноль) Разве вы не знаете, что это такое?   -  person Aspid    schedule 23.04.2020
comment
Проверьте stackoverflow.com /questions/26091463/ это очевидно связано с сущностью групп приложений   -  person ares777    schedule 28.04.2020


Ответы (1)


Убедитесь, что ваше расширение клавиатуры включило полный доступ. Если нет, я боюсь, что вы не можете получить доступ к общим данным, даже сохранить в UserDefaults между расширениями и родительским приложением.

person ares777    schedule 28.04.2020
comment
Это помогает. Каждый раз, когда вы сбрасываете устройство в симуляции или запускаете симуляцию на другом устройстве, этот флаг сбрасывается на false. Извините, срок действия награды истек, я не могу дать вам награду. - person Aspid; 28.04.2020