Пытаюсь использовать 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: []
Я ожидаю, что объекты, которые я сохранил в приложении, смогут получить расширение и наоборот.
Что я делаю не так с файлом базы данных?