#core-data #swiftui #cloudkit
#основные данные #свифтуи #cloudkit
Вопрос:
В настоящее время я разрабатываю приложение на основе SwiftUI с основными данными и синхронизацией CloudKit с NSPersistentCloudKitContainer
.
Я нашел различные решения, как переключать синхронизацию основных данных CloudKit во время выполнения, также здесь, в переполнении стека. Основная идея этих решений заключается в следующем.
- создайте новый экземпляр
NSPersistentCloudKitContainer
- набор
storeDescription.cloudKitContainerOptions = nil
- хранилище сохраняемости загрузки
Большинство решений рекомендуют перезапустить приложение вручную, чтобы избежать именно моей проблемы, описанной ниже.
Проблемы
Пока все хорошо. Как я могу распространять новый viewContext через свое приложение SwiftUI во время выполнения. В главном приложении я распространил viewContext во время запуска через @Environment(.managedObjectContext)
, и, похоже, он не обновляется автоматически после повторной инициализации NSPersistentCloudKitContainer
.
var body: some Scene { WindowGroup { ContentView() .environment(.managedObjectContext, persistence.container.viewContext) } }
После деактивации синхронизации CloudKit я получаю следующую ошибку при попытке добавить новый объект.
[error] warning: Multiple NSEntityDescriptions claim the NSManagedObject subclass 'TestEntity' so entity is unable to disambiguate.
Есть какие-нибудь идеи? Является ли это проблемой @Environment
концепции?
Обновление: 12.12.2021: Исправлена повторная инъекция viewContext
Я исправил проблему, чтобы повторно ввести viewContext
следующие изменения.
Сначала я ввел @Published var persistenceContainerReloaded: Int = 0
атрибут в Persistence
класс. Каждый раз, когда я переключаю синхронизацию CloudKit, я переключаюсь между NSPersistentCloudKitContainer
и NSPersistentContainer
. После этого я увеличиваю атрибут persistenceContainerReloaded
на 1. Строка .id(persistence.persistenceContainerReloaded)
запускает перезагрузку иерархии полного представления. Теперь каждое представление использует правильный экземпляр viewContext.
@main struct TargetShooterApp: App { @StateObject var persistence: Persistence = Persistence.shared var body: some Scene { WindowGroup { ContentView() .environment(.managedObjectContext, persistence.container.viewContext) .id(persistence.persistenceContainerReloaded) } } }
Но я все еще сталкиваюсь с некоторыми проблемами в своем решении. Я все еще вижу результаты отладки CoreData CloudKit в терминале, хотя storeDescription.cloudKitContainerOptionsis
они равны нулю. Устройство по-прежнему может синхронизировать локальные изменения с другими устройствами, но не может принимать изменения, внесенные на других устройствах. После перезапуска приложения все работает так, как ожидалось. Похоже, все еще работает фоновый процесс NSCloudKitMirroringDelegate
, загружающий изменения в CoreData.
Есть какие-нибудь идеи?