【发布时间】:2021-07-19 23:44:01
【问题描述】:
我有一个使用公共数据库的应用程序,它使用 Core Data 和 CloudKit。问题是删除似乎永远不会同步,添加和更改直到应用程序进入后台然后返回前台才会显示,甚至这些结果也不一致。
示例应用只是您在指定 SwiftUI 和 Core Data 时获得的默认应用。我在 CloudKit 仪表板中修改了 Schema,添加了两个索引 recordName 和 modifiedAt。
下面是 Persistence.swift 文件,所以要复现,新建一个项目,选择 Core Data 和 Use CloudKit,Add Capability for CloudKit 和 Remote Notifications,然后将 Persistence.swift 内容替换为上面的内容。
import CoreData
struct PersistenceController {
static let shared = PersistenceController()
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
for _ in 0..<10 {
let newItem = Item(context: viewContext)
newItem.timestamp = Date()
}
do {
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
return result
}()
let container: NSPersistentCloudKitContainer
init(inMemory: Bool = false) {
container = NSPersistentCloudKitContainer(name: "TestCKSink")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
guard let description = container.persistentStoreDescriptions.first else
{
fatalError()
}
//description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
description.cloudKitContainerOptions?.databaseScope = .public
container.viewContext.transactionAuthor = "Me"
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
}
}
我已经尝试过启用和不启用历史跟踪选项。正如我所说,这在某些时候有效。我也意识到我需要添加代码来强制刷新显示,但即使检查 CloudKit 仪表板并查询记录,有些根本没有显示在那里或需要很长时间才能到达(18 分钟)。
欢迎提出任何建议。
【问题讨论】:
-
这里有一个WWDC video,看起来您缺少基本设置中的一些代码,例如
setQueryGenerationForm,您应该查看整个视频,但代码似乎在第 2 分钟左右: 57 -
感谢您的回复。这并没有帮助,当 Nick Gillette 审查代码时,他将代码排除在同步工作所需的内容之外。不太清楚它的作用。
-
我并没有完全解决这个问题,但我怀疑我所看到的是公共数据库中的一些损坏,导致同步无法 100% 工作。当我从公共选项切换到私人选项时,事情开始起作用了。我怀疑这是因为我又从头开始了,不知道使用公共数据库是否有什么意义。我最终会尝试清除公共数据库并切换回它,届时将发布结果。在我这样做之前可能需要一段时间。
-
我相信 2020 年的 WWDC 视频中提到只有私有数据库会收到推送通知。这个想法是公共数据库用于模板和稀有共享对象。因此,您必须显式轮询以获取更新。切换到私有数据库使其工作。我不喜欢这如何限制由公共 CloudKit 数据库支持的核心数据的用例。当您直接访问 Cloudkit 数据库时,支持更改推送通知。我过去曾让这些订阅工作。如果可以选择获得该功能,我会很高兴!
-
我没有使用“at”FetchRequest,而是使用例程直接读取数据库。一旦我将其更改为“at”FetchRequest,它就可以正常工作,但我也发现模拟器很少正常工作,但实际设备可以正常工作,但有一些例外。