Как вызвать WidgetCenter.shared.reloadAllTimelines () при изменении основных данных в CloudKit?

У меня есть приложение, использующее Core Data с CloudKit. Изменения синхронизируются между устройствами. Основная цель имеет возможность фоновых режимов с отмеченным Remote notifications, возможность iCloud проверяется с помощью служб, для которых установлено значение CloudKit, и проверяется правильный контейнер в контейнерах.

Как я могу реагировать в коде на изменения, удаление и добавление записей? Мне нужно позвонить WidgetCenter.shared.reloadAllTimelines(), когда основные данные в CloudKit изменятся, чтобы обновить виджет рабочего стола iOS 14.

Моя цель - заставить это работать: я изменяю / добавляю / удаляю запись на icloud.developer.apple.com или другом устройстве, и WidgetCenter.shared.reloadAllTimelines() вызывается для отображения правильных данных в виджете. Приложение может быть на заднем или переднем плане.

От AppDelegate.swift:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Register for Remote Notifications
    application.registerForRemoteNotifications()
    
    return true
}

Также заметили сообщения в журнале вывода:

CoreData: debug: CoreData + CloudKit: - [NSCloudKitMirroringDelegate remoteStoreDidChange:] _ block_invoke (2138): ‹NSCloudKitMirroringDelegate: 0x281818d00› - Игнорирование удаленного уведомления об изменении, потому что экспортер уже догнал эту транзакцию: URL: файл: ///var/mobile/Containers/Data/Application/F83C68DA-7C36-42CC-926D-7C721C679579/Library/Application%20Support/AppTitle.sqlite)


person Igor R.    schedule 19.09.2020    source источник


Ответы (1)


Если вы хотите подписаться на удаленные уведомления Core Data, вы можете использовать onReceive:

struct WidgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        Text(entry.date, style: .time)
            .onReceive(NotificationCenter.default.publisher(for: .NSPersistentStoreRemoteChange)) { _ in
                // make sure you don't call this too often
                WidgetCenter.shared.reloadAllTimelines()
            }
    }
}

Просто убедитесь, что вы не звоните reloadAllTimelines() слишком часто - вероятно, для вашего виджета доступно ограниченное количество обновлений.

person pawello2222    schedule 19.09.2020