SwiftUI CoreData NSManagedObjectContext в среде - PullRequest
6 голосов
/ 19 января 2020

У меня проблема с выставлением моего NSManagedObjectContext в среду SwiftUI. Вот мой код:

extension SceneDelegate: UIWindowSceneDelegate {

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = scene as? UIWindowScene else { return }

        let window = UIWindow(windowScene: windowScene)
        let context = PersistentContainer.shared.viewContext

        let rootView = TabBarView().environment(\.managedObjectContext, context)
        window.rootViewController = UIHostingController(rootView: rootView)

        self.window = window
        window.makeKeyAndVisible()
    }
}

class PersistentContainer: NSPersistentContainer {
    static let shared = PersistentContainer()

    private convenience init() {
        self.init(name: "App")

        viewContext.mergePolicy = NSMergePolicy(merge: .mergeByPropertyStoreTrumpMergePolicyType)
        viewContext.automaticallyMergesChangesFromParent = true

        loadPersistentStores { description, error in
            if let error = error {
                fatalError("Unable to load persistent stores: \(error)")
            }
        }
    }
}

struct CategoriesView: View {
    @Environment(\.managedObjectContext) var context

    @FetchRequest(entity: CoreCategory.entity(),
                  sortDescriptors: [
                    NSSortDescriptor(keyPath: \CoreCategory.createdAt, ascending: true)
                  ]
                 ) var categories: FetchedResults<CoreCategory>
}

Мой CategoriesView - это мой root вид, поэтому доступ к контексту происходит при запуске приложения. Я получаю следующую ошибку при запуске моего приложения ...

[error] warning:  View context accessed for persistent container App with no stores loaded

... но представление может нормально отображать результаты. Кроме того, если я представлю модальное представление, которое содержит SwiftUI @FetchRequest в том же формате, что и мой CategoriesView, приложение вылетает со следующей ошибкой:

[SwiftUI] Context in environment is not connected to a persistent store coordinator: <NSManagedObjectContext: 0x600002348b60>

Из всех учебных пособий, которые я нашел в Интернете, я выставив мой NSManagedObjectContext рекомендуемый способ. У меня ощущение, что это связано с тем, что loadPersistentStores является асинхронным, но контекст устанавливается в Среде синхронно. Кто-нибудь еще может заставить CoreData работать в SwiftUI?

Ответы [ 2 ]

3 голосов
/ 20 января 2020

Понял, что вызывает оба сообщения об ошибках здесь. Первая ошибка исходит от моего PersistentContainer синглтона. Я переместил две строки, конфигурирующие viewContext, в блок завершения loadPersistentStores, и эти предупреждения исчезли:

private convenience init() {
    self.init(name: "App")

    loadPersistentStores { description, error in
        viewContext.mergePolicy = NSMergePolicy(merge: .mergeByPropertyStoreTrumpMergePolicyType)
        viewContext.automaticallyMergesChangesFromParent = true

        if let error = error {
            fatalError("Unable to load persistent stores: \(error)")
        }
    }
}

Вторая проблема, очевидно, связана с SwiftUI начиная с бета-версий. Об этом на форуме разработчиков Apple здесь . Вы можете сделать это в качестве обходного пути:

.sheet(isPresented: $isPresentingCategoryPicker) {
    CategoriesView()
        .environment(\.managedObjectContext, self.context)
}

Кажется, что среда очищается для модально представленных контроллеров представления.

0 голосов
/ 18 февраля 2020

Что касается второй проблемы, я увидел учебник, объясняющий, что когда вы представляете представление модально, оно фактически добавляет подпредставление, поэтому контекст должен быть self.context.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...