Как получить данные CloudKit вручную, чтобы обновить пользовательский интерфейс, используя NSPersistentCloudKitContainer и SwiftUI? - PullRequest
1 голос
/ 23 февраля 2020

Допустим, у нас есть работающий NSPersistentCloudKitContainer и только одна сущность CoreData с именем Item. Давайте предположим, что мы хотим синхронизировать c между iOS, iPad и приложением Ma c.

Я наблюдал этот WWD C сеанс о синхронизации CoreData и CloudKit и реализовал основные c syn c в моем приложении SwiftUI. Это работает, и данные поступают на все 3 устройства и синхронизируются автоматически.

Но на Ма c данные не отображаются без перезагрузки представления (а также в симуляторах (потому что они не получают пу sh-Уведомления). Приходит, но нет автоматов c refre sh. Я также тестировал симулятор на реальном устройстве, а иногда он синхронизируется автоматически, иногда мне нужно заново открыть приложение, чтобы увидеть изменения .

Мне любопытно, есть ли метод принудительной выборки, который можно использовать вместе с NSPersistentCloudKitContainer, или, может быть, кто-нибудь знает обходной путь для ручной перезагрузки данных при использовании NSPersistentCloudKitContainer с SwiftUI?

Я также хочу чтобы показать индикатор активности, когда новые данные начинают появляться, но не знаете, где найти этот момент начала получения выборок в коде?

Я использовал этот пример кода UIKit , предоставленный Apple и адаптировал его для работы в SwiftUI. Я также прочитал всю документацию здесь .

Вот Код persistentContainer, который я использую:

lazy var persistentContainer: NSPersistentCloudKitContainer = {

        let container = NSPersistentCloudKitContainer(name: "AppName")

        container.persistentStoreDescriptions.first?.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)

        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {

                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })

        container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        container.viewContext.automaticallyMergesChangesFromParent = true

        return container
    }()

Если вы видите, я не включил container.viewContext.transactionAuthor = appTransactionAuthorName и setQueryGenerationFrom(.current) и NotificationCenter.default.addObserver в приведенный выше код. Но я тоже пытался с ними и получал те же результаты. Не уверен, нужно ли мне вообще их использовать, потому что синхронизация работает и без этих вызовов.

В своем классе Item я добавил эту функцию для получения элементов:

   static func getAllItems() -> NSFetchRequest<Item> {

        let request: NSFetchRequest<Item> = Item.fetchRequest() as! NSFetchRequest<Item>

        let sortDescriptor = NSSortDescriptor(key: "name", ascending: false)

        request.sortDescriptors = [sortDescriptor]

        return request

    }

В моем ContentView у меня есть это представление MasterView:

    struct MasterView: View {

    @FetchRequest(fetchRequest: Item.getAllItems()) var items: FetchedResults<Item>

    @Environment(\.managedObjectContext) var viewContext

    var body: some View {
        List {
            ForEach(items, id: \.self) { item in
                NavigationLink(
                    destination: DetailView(item: item)
                ) {
                    Text("\(item.name ?? "")")
                }
            }.onDelete { indices in
                self.items.delete(at: indices, from: self.viewContext)
            }
        }
    }
}

PS Я также заметил, что syn c работает медленно (возможно, это только мой случай, не уверен). Я должен ждать от 5 до 10 секунд между синхронизациями с этим кодом. Может кто знает, нормально ли это время ожидания или нет?

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