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