Регистрация для получения уведомлений об удаленных изменениях CloudKit не работает - PullRequest
1 голос
/ 31 октября 2019

Я только что закончил настройку CoreData + CloudKit, используя новую iOS 13 NSPersistentCloudKitContainer. Он работает очень хорошо, потому что я могу использовать автоматически сгенерированные классы CoreData для доступа к свойствам и локального хранилища, а NSPersistentCloudKitContainer автоматически синхронизирует изменения между устройствами. У меня проблема с уведомлением об удаленных изменениях. Я проверил документацию Apple, и в ней говорится, что вы NSPersistentCloudKitContainer NSPersistentStoreDescription говорите, что хотите отправить уведомление, а затем регистрируете другие объекты в качестве наблюдателей этого уведомления. Я сделал это и добавил метод тестирования, чтобы показать, когда были обнаружены удаленные изменения. Оповещение, генерируемое тестовым методом, никогда не генерируется, но если я убью приложение и снова открою его, изменения будут немедленно внесены. Поэтому я считаю, что удаленные изменения синхронизируются и интегрируются в локальное хранилище CoreData, но уведомление не работает. Я добавил право Background Modes к своей цели и выбрал режим Remote notification. Код ниже. Любая помощь будет принята с благодарностью!

Настройка опции для отправки уведомления:

- (NSPersistentCloudKitContainer *)persistentContainer {
    // The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it.
    @synchronized (self) {
        if (_persistentContainer == nil) {
            _persistentContainer = [[NSPersistentCloudKitContainer alloc] initWithName:@"<redacted>"];
            [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
                if (error != nil) {
                    // ...
                }
                else {
                    // ...

                    [storeDescription setOption:@(YES) forKey:NSPersistentStoreRemoteChangeNotificationPostOptionKey];

                    // ...
                }
            }];
        }
    }

    return _persistentContainer;
}

Регистрация для получения уведомления:

- (void)viewDidLoad {
    [super viewDidLoad];

    // ...

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changes) name:NSPersistentStoreRemoteChangeNotification object:[CoreDataFunctions persistentContainer]];
}

Метод теста для реагирования на изменения:

- (void)changes {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Changes received" message:nil preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
    [alert addAction:ok];
    [self presentViewController:alert animated:YES completion:nil];
}

1 Ответ

0 голосов
/ 02 ноября 2019

Везде, где вы получаете доступ к постоянному контейнеру CloudKit вашего приложения для захвата viewContext, вам нужно установить для свойства automaticallyMergesChangesFromParent значение true.

lazy var managedContext: NSManagedObjectContext = {
    self.storeContainer.viewContext.automaticallyMergesChangesFromParent = true
    return self.storeContainer.viewContext
}()

Внесение этого однострочного изменения активируетприложение (которое поддерживается NSFetchedResultsController) для обновления пользовательского интерфейса в ответ на удаленные изменения данных…

...