CoreData в расширении: как использовать базу данных в общей группе - PullRequest
0 голосов
/ 06 марта 2020

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

В моем приложении я сделал ленивый var для хранения 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()

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

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: 0x9f53bbaee) (data: 0x9f53bbae) entity: Entity; id: 0x9f53fc35e42bbbae; data: {name = "test from app";})]

Я проделал то же самое в своем расширении, добавил lazy var secureAppGroupPersistentStoreURL, создал PersistentContainer to 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")
    }
    //...
}

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

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

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

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

1 Ответ

1 голос
/ 28 апреля 2020

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

...