注册以接收远程 CloudKit 更改的通知不起作用

Posted

技术标签:

【中文标题】注册以接收远程 CloudKit 更改的通知不起作用【英文标题】:Registering to receive notifications of remote CloudKit changes not working 【发布时间】:2020-02-26 16:20:48 【问题描述】:

我刚刚使用新的 ios 13 NSPersistentCloudKitContainer 完成了 CoreData+CloudKit 的设置。它工作得非常好,因为我可以使用自动生成的 CoreData 类进行属性访问和本地存储,NSPersistentCloudKitContainer 自动同步设备之间的更改。我遇到的问题是收到远程更改的通知。我检查了 Apple 文档,这表明您告诉 NSPersistentCloudKitContainerNSPersistentStoreDescription 您希望它发送通知,然后将其他对象注册为该通知的观察者。我已经这样做了,并添加了一个测试方法来显示何时检测到远程更改。测试方法生成的警报永远不会生成,但如果我杀死应用程序并重新打开它,更改会立即出现。所以我相信远程更改正在同步并集成到本地 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】:

你观察到的是持久化容器而不是 store coordinator,应该是这样的:

[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(persistentStoreRemoteChangeNotification:) name:NSPersistentStoreRemoteChangeNotification object:_persistentContainer.persistentStoreCoordinator];

【讨论】:

【参考方案2】:

无论您在何处访问应用的持久 CloudKit 容器以获取 viewContext,您都需要将 automaticallyMergesChangesFromParent 属性设置为 true

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

进行这一行更改将使应用程序(由NSFetchedResultsController 支持)能够更新 UI 以响应远程数据更改……

【讨论】:

是的,解决了 - 谢谢!!!启用此选项后,通知开始触发并打开带有更新内容的 ViewControllers 开始显示添加到其他设备上的信息。谢谢!!!!!我希望 Apple 在这方面的文档更好......

以上是关于注册以接收远程 CloudKit 更改的通知不起作用的主要内容,如果未能解决你的问题,请参考以下文章

CloudKit 不发送更新通知

私有数据库和订阅的 Cloudkit 问题?

CloudKit 推送通知订阅不起作用

注册远程通知在 Xcode 6 中不起作用

在 iOS (swift) 应用中,第二个 Firebase 应用的注册无法接收远程通知

swift Swift - CloudKit - 为远程通知配置应用程序