我正在比较 CKRecord 的版本,使用recordChangeTag,我看到随着时间的推移,值从n9(2 个字符)更改为1c1(3 个字符)。
在苹果文档中:
在您自己的代码中,您可以使用更改标记来区分同一记录的两个不同版本。
我想问一下:
当我使用保存策略保存包含CKAsset(只是 JPG 图像)的记录时,我正在测试同步冲突。我收到错误。这会返回用于解决冲突的有用信息,包括我尝试保存的信息以及记录的当前服务器版本。第一个在,第二个在。CKModifyRecordsOperation.IfServerRecordUnchangedCKErrorCode.ServerRecordChangedCKErrorCKRecorderror.userInfo[CKRecordChangedErrorClientRecordKey]error.userInfo[CKRecordChangedErrorServerRecordKey]
我的问题是我尝试使用以下代码访问服务器记录的 CKAsset:
if let photoAsset = rec["myPhoto"] as? CKAsset {
print("PhotoAsset.fileURL: \(photoAsset.fileURL)") // BAD_ACCESS ERROR HERE
self.myPartner.photo = NSData(contentsOfURL: photoAsset.fileURL)
}
Run Code Online (Sandbox Code Playgroud)
我不明白这怎么可能。但经过进一步调查,我打印出了客户端和服务器 CKRecords,而服务器缺少“路径”属性。
客户端 CKAsset...myPhoto (已修改)-> CKAsset:0x7b960d90;路径=~/tmp/BF185B2C-7A39-4730-9530-9797E843243A照片,大小=373959,uploadRank=0,uploadReceipt=A92Eg1qoyPG7yrg3,UUID=3C2D5DC8-4FF5-4A81-853B-395FC1C59862,referenceSignature=<012 fd149 200fc600 617e3907 88763e3e 5002abbf 5b> 、flags=已上传、wrappedEncryptionKey=、签名=<0134a297 38d52f5f 9275bfba fce5b1a8 3d6b9692 d3>
服务器 CKAsset...myPhoto = CKAsset: 0x7be700d0; ReferenceSignature=<015337bd 84409893 7c014f46 36248d27 ce911dc3 7a>,大小=373959,uploadRank=0,UUID=DF5D2EB4-033C-49A2-AF52-6055B5A44106,wrappedEncryptionKey=<767e7cfd d1e62 110 32119ee9 f6f026b3 5bcf0cc3 8053a4de>,签名=<0134a297 38d52f5f 9275bfba fce5b1a8 3d6b9692 d3>
请注意,path=~/tmp/C706423B-A3E8-4051-A9B3-483C718BFBF5photo服务器中缺少什么?谁能解释一下吗?为了解决这个问题,我尝试避免接触服务器记录中的 CKAsset。我希望至少能够检查是否为零。我想把它放在那里以防对其他人有帮助。
有时NSPersistentCloudKitContainer会在控制台中报告错误,如下所示:
*2020-04-14 16:41:27.725794+0100 ExampleApp[9736:8226377] [error] error: CoreData+CloudKit: -: <NSCloudKitMirroringDelegate: 0x282b944d0>: Sending \xe2\x80\x98NSCloudKitMirroringDelegateWillResetSyncNotificationName\xe2\x80\x99 with reason: \xe2\x80\x98UserPurgedZone\xe2\x80\x99* [NSCloudKitMirroringDelegate logResetSyncNotification:](1798) \nRun Code Online (Sandbox Code Playgroud)\n\n在我的代码中,我在加载持久存储时进行了错误处理,但此错误不会触发它,因为此错误是在存储加载后发生的。
\n\n我在哪里处理这些错误?我怎样才能看到代码中的这些错误?
\n在开发过程中,我已经转向NSPersistentCloudKitContainer并开始了尝试测试尽可能多的场景以确保没有人丢失任何数据的可怕过程。
在一些测试中我看到了这样的错误:
<CKError 0x28033a310: "Partial Failure" (2/1011); "Failed to modify some records"; uuid = B6015357-50E0-40B3-949F-1557F59A23DB; container ID = "iCloud.com.xxxx.yyyyyy"; partial errors: {
F023EFDF-B9DE-4C17-872B-01C34C0DF129:(com.apple.coredata.cloudkit.zone:__defaultOwner__) = <CKError 0x280266fa0: "Invalid Arguments" (12/2006); server message = "Cannot create or modify field 'CD_someField' in record 'CD_someRecord' in production schema"; uuid = B6015357-50E0-40B3-949F-1557F59A23DB>
... 399 "Batch Request Failed" CKError's omited ...
}>
Run Code Online (Sandbox Code Playgroud)
我能够修复这个问题,但它只会影响某些场景,如果这种情况发生在真正的用户身上,他们(和我)将永远不会知道这个问题,并且他们的数据也不会同步到 CloudKit。
如果商店无法加载,您会收到一个错误,但如果它加载但不同步,则不会。
所以我的问题是:有没有办法接收代码中的此类错误?
我寻找了通知和委托方法,但找不到。
我发现.NSPersistentStoreRemoteChange通知被多次收到,有时多达 10 次。
我认为这没有害处,但最好的情况是它会耗尽处理能力。
\n所以我的问题是:
\n--
\n我有以下代码来设置我的容器。它包含在单例的初始化程序中,我已经确认它被调用一次。
\nguard let modelURL = Bundle(for: type(of: self)).url(forResource: momdName, withExtension:"momd"),\n let mom = NSManagedObjectModel(contentsOf: modelURL)\n else {\n fatalError(" Error loading model from bundle")\n }\n \n let containerURL = folderToStoreDatabaseIn.appendingPathComponent("Model.sqlite")\n \n container = NSPersistentCloudKitContainer(name: momdName, managedObjectModel: mom)\n \n guard let description = container.persistentStoreDescriptions.first else {\n fatalError(" ###\\(#function): Failed to retrieve a persistent store description.")\n }\n \n description.url = …Run Code Online (Sandbox Code Playgroud) 我目前正在制作一个应用程序,需要它的 CoreData 存储通过 iCloud 跨设备同步。
一切正常,只是不是实时同步。(或者至少有点接近)。当 Device1 更改某些内容后我在 Device2 上什么都不做时,它根本不同步。事实上,我必须最小化并重新打开 Device2 上的应用程序才能使同步正常工作。
这很好地证明了这一点:(来源)
这是我的代码片段:
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 …Run Code Online (Sandbox Code Playgroud) 我有一个 iOS + watchOS 应用程序,我想使用相同的数据模型。所以我创建了一个 CoreData 堆栈,并为NSPersistentCloudKitContainer.
我的 iOS 应用程序可以访问 CloudKit 容器,因为我可以从控制台中的日志中读取内容,但是当我的 watchOS 应用程序想要连接到 CloudKit 容器(与iCloud.foo.myIDiOS 应用程序相同)时,我收到一条错误消息Invalid bundle ID for container: .
我尝试了几个新容器。我还尝试一次又一次地检查功能窗格上的所有复选框。
我错过了什么吗?
(我还阅读了Core data + CloudKit - iOS 和 watchOS 配套应用程序之间的共享,但这没有帮助)
该应用程序使用 Core Data + CloudKit。当应用程序启动时,WidgetKit 会从核心数据中获取正确的条目,但是当我从主应用程序向核心数据添加新条目并调用WidgetCenter.shared.reloadTimelines()更新的条目时,不会获取到旧数据,并且旧数据会显示在小部件内。
主应用程序和小部件目标具有相同的应用程序组,两个目标都启用了 iCloud 功能。
当我WidgetCenter.shared.reloadTimelines()从主应用程序调用小部件重新加载(添加到小部件视图的计时器设置为零)但从核心数据获取时,不会返回新添加的条目。然后我重新启动应用程序并获取正确的条目。
为什么当 WidgetCenter.shared.reloadTimelines() 被调用时它不获取正确的条目并且仅在应用程序重新启动时才起作用?
小部件的代码:
import WidgetKit
import SwiftUI
import CoreData
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> HabitsEntry {
HabitsEntry(date: Date(), habitsCount: 0)
}
func getSnapshot(in context: Context, completion: @escaping (HabitsEntry) -> ()) {
let entry = HabitsEntry(date: Date(), habitsCount: 0)
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
let managedObjectContext = Storage.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "DailyHabit")
let predicate …Run Code Online (Sandbox Code Playgroud) 有人在 WatchKit + CoreData + CloudKit 上遇到过这个错误吗?
CoreData:调试:CoreData + CloudKit:-[PFCloudKitMetadataModelMigratorcalculateMigrationStepsWithConnection:错误:](404):跳过“ANSCKDATABASEMETADATA”的迁移,因为它已经有一个名为“ZLASTFETCHDATE”的列
请注意,该应用程序可以运行,并且我在模拟器或真实手表上运行该应用程序时没有遇到任何问题。其中有 9 个“错误”。
我认为这与下面持久容器的设置方式有关。
description.setOption(true as NSObject, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
...
container.viewContext.automaticallyMergesChangesFromParent = true // bring all iCloud changes into app
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy // iCloud wins, local memory loses
Run Code Online (Sandbox Code Playgroud) App Groups遗憾的是,watchOS 仍然不支持 NSUbiquitousKeyValueStore,并且NSUbiquitousKeyValueStore可用于除 watchOS 之外的每个平台。我读过保持你的 watchOS 内容最新并提到了 iCloud,他们让它听起来很简单,但没有提供示例。看来我必须创建一个完整的客户端CloudKit基础设施来支持它,这似乎有点矫枉过正,然后要求其他平台也做同样的事情,因为 watchOS 是个奇怪的球。
我在 watchOS 中是否缺少一个简单的键/值 iCloud 存储等效项?当你添加 watchOS 时,共享云数据似乎真的很困难。我尝试使用 iPhone 作为事实来源并与 watchOS 进行通信,但非常笨重,并且要求它们彼此处于范围内,否则就会变得不同步。任何帮助或指导将不胜感激!