CoreData + CloudKit 仅在最小化和重新打开应用程序后同步

Posted

技术标签:

【中文标题】CoreData + CloudKit 仅在最小化和重新打开应用程序后同步【英文标题】:CoreData + CloudKit only synching after minimizing and reopening app 【发布时间】:2020-09-26 08:25:12 【问题描述】:

我目前正在制作一个需要通过 iCloud 跨设备同步其 CoreData 存储的应用。

一切正常,只是它不是实时同步的。 (或者至少有点接近)。在 Device1 更改某些内容后,当我在 Device2 上什么都不做时,它根本不同步。事实上,我必须最小化并重新打开 Device2 上的应用程序才能使同步正常工作。

这很好地证明了这一点:(source)

这是我的代码的 sn-p:

let container: NSPersistentCloudKitContainer
var context: NSManagedObjectContext  container.viewContext 

init() 
    container = NSPersistentCloudKitContainer(name: "__Decision")
    
    guard let description = container.persistentStoreDescriptions.first else  ... 
    description.setOption(true as NSObject, forKey:
        NSPersistentStoreRemoteChangeNotificationPostOptionKey)
    
    container.loadPersistentStores(completionHandler:  ... )
    
    container.viewContext.automaticallyMergesChangesFromParent = true
    container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    
    NotificationCenter.default.addObserver(self, selector: #selector(self.processUpdate), name: .NSPersistentStoreRemoteChange, object: nil)



@objc func processUpdate(notification: NSNotification) 
    operationQueue.addOperation 
        DispatchQueue.main.async  ...  //Fetch new synched data and update UI 
    

    
    
lazy var operationQueue: OperationQueue = 
    var queue = OperationQueue()
    queue.maxConcurrentOperationCount = 1
    return queue
()

我遵循了苹果的文档和其他教程,因为这是我第一个使用 CloudKit + CoreData 的项目。

一切似乎都与他们所做的相同。我不知道,并且从几天以来一直在研究这个问题。

谢谢!

【问题讨论】:

我遇到了完全相同的问题,即使关闭和打开应用程序也是如此。我也有同样的问题。我再次按照所有说明进行操作,确保设置了远程通知并且它有效。您的代码看起来不错,可能是设置 嗯,那我也应该做,谢谢你的帮助。 尝试在您的 didFinishLaunchingWithOptions 中调用 application.registerForRemoteNotifications() 并确保在 Sign 选项卡中添加 PushNotifcations 如果您将 NSPersistentStoreDescription 设置为通过 description.cloudKitContainerOptions?.databaseScope = .public 与公共数据库而不是私有数据库(我相信是 ios 14 之前的默认值)进行交互,它只会每 30 分钟轮询一次来自 cloudkit 的更改按设计(参见 WWDC 2020 会议视频中关于此主题的 10:30:developer.apple.com/videos/play/wwdc2020/10650) 【参考方案1】:

我只是向您展示我的设置,因为我曾经遇到过同样的问题。我也在使用 CloudKit 进行 macOS 和 iOS 同步,它现在可以工作了。使用 SwiftUI 更新视图。

在我的 AppDelegate 中,我首先注册 remoteNotification

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 
    // Override point for customization after application launch.
    
    application.registerForRemoteNotifications()
    
    return true

我的 persistenContainer 看起来确实像你的:

lazy var persistentContainer: NSPersistentCloudKitContainer = 
    let container = NSPersistentCloudKitContainer(name: "name")
    
    container.loadPersistentStores(completionHandler:  (storeDescription, error) in
        if let error = error as NSError? 
            fatalError("Unresolved error \(error), \(error.userInfo)")
        
    )
    
    container.viewContext.automaticallyMergesChangesFromParent = true
    container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
    
    return container
()

然后是我的签名选项卡,添加背景模式:

.. 并添加 Push 和 iCloud

另外,请耐心等待。有时同步确实需要几分钟才能更新。

【讨论】:

嘿,再次感谢您帮助我。不知何故它现在工作!我不知道application.registerForRemoteNotifications(),但这是我所做的: - 清理了构建文件夹。 - 从我所有的设备中删除该应用程序。 - 完全摆脱当前应用程序的 iCloud 数据。然后它又开始工作了......我来做这个是因为我用CoreData和CloudKit完全相同的代码制作了一个简单的虚拟应用程序并且它工作......?‍♀️

以上是关于CoreData + CloudKit 仅在最小化和重新打开应用程序后同步的主要内容,如果未能解决你的问题,请参考以下文章

从 CloudKit 获取并保存到 CoreData

iOS swift:使用 coredata (cloudkit) 存储缓存

CloudKit 和 CoreData 默认值

iOS 上的 CloudKit + CoreData 和 watchOS 同步不起作用

来自 com.apple.xpc.activity.com.apple.cloudkit.scheduler.com.apple.coredata.cloudkit.activity.export 的

使用 NSPersistentCloudKitContainer 时,CoreData 架构更改未部署到 CloudKit