我发现.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 进行通信,但非常笨重,并且要求它们彼此处于范围内,否则就会变得不同步。任何帮助或指导将不胜感激!
运行 iOS 14.x 或更低版本的 UICloudSharingController 将“添加人员”显示为“人员”表第一部分的最后一行。
从 iOS 15.x(包括新的 15.2 beta)开始,包含“添加人员”的行不存在。
在苹果解决这个问题之前,有人知道解决办法吗?Apple 第一方应用程序(例如笔记)似乎不受此问题的影响,但我所有使用 UICloudSharingController 共享的应用程序都出现此问题,即使是那些未在 xcode 13.x 下重新编译的应用程序
let publicDB = CKContainer.init(identifier: "iCloud.com.xxxx.xxxx").publicCloudDatabase
let query = CKQuery(recordType: "TestUsers", predicate: NSPredicate(value: true))
publicDB.perform(query, inZoneWith: nil) { records, error in
print(error)
print(records)
}
Run Code Online (Sandbox Code Playgroud)
<CKError 0x282ae46f0:“权限失败”(10/2007);
服务器消息 =“容器的捆绑包 ID 无效”;
操作=XXXXX;uuid = XXXXX-XXXX-XXXXX-XXXXX-XXXXXX;
容器 ID =“iCloud.com.xxxx.xxxx”>
我使用 NSPersistentCloudKitContainer 将对象保存在 CoreData + CloudKit 中。我集成了一个共享功能,可将对象移动到单独的区域以使用 UICloudSharingController 进行共享,如中所述https://developer.apple.com/wwdc21/10015
当用户停止共享时,我希望删除共享区域中的对象,并将其移回CoreData + CloudKit标准私有区域。使用以下方法删除 CKShare 及其区域:
/**
Delete the Core Data objects and the records in the CloudKit record zone associcated with the share.
*/
func purgeObjectsAndRecords(with share: CKShare, in persistentStore: NSPersistentStore? = nil) {
guard let store = (persistentStore ?? share.persistentStore) else {
print("\(#function): Failed to find the persistent store for share. \(share))")
return
}
persistentContainer.purgeObjectsAndRecordsInZone(with: share.recordID.zoneID, in: store) { (zoneID, error) in
if let error = error {
print("\(#function): …Run Code Online (Sandbox Code Playgroud) 我有一个可用的 CoreData 应用程序(本地存储)。
我想让它可以与 iCloudKit 一起使用。
从 迁移NSPersistentContainer到NSPersistentCloudKitContainer(CoreDataStack.swift,第 21 行)后,我希望能够在接下来的测试中取得成功。
但是,我陷入了步骤 2。经过多次尝试,我仍然收到以下与 iCloud 相关的错误。
这是完整的错误日志。
CoreData: debug: CoreData+CloudKit: -[PFCloudKitOptionsValidator validateOptions:andStoreOptions:error:](36): Validating options: <NSCloudKitMirroringDelegateOptions: 0x600001c0d050> containerIdentifier:iCloud.com.yocto.xxx databaseScope:Private ckAssetThresholdBytes:<null> operationMemoryThresholdBytes:<null> useEncryptedStorage:NO useDeviceToDeviceEncryption:NO automaticallyDownloadFileBackedFutures:NO automaticallyScheduleImportAndExportOperations:YES skipCloudKitSetup:NO preserveLegacyRecordMetadataBehavior:NO useDaemon:YES apsConnectionMachServiceName:<null> containerProvider:<PFCloudKitContainerProvider: 0x600002c08770> storeMonitorProvider:<PFCloudKitStoreMonitorProvider: 0x600002c08730> metricsClient:<PFCloudKitMetricsClient: 0x600002c087d0> metadataPurger:<PFCloudKitMetadataPurger: 0x600002c08790> scheduler:<null> notificationListener:<null> containerOptions:<null> defaultOperationConfiguration:<null> progressProvider:<NSPersistentCloudKitContainer: 0x600003b00b00> test_useLegacySavePolicy:YES archivingUtilities:<PFCloudKitArchivingUtilities: 0x600002c08800>
storeOptions: {
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;
NSPersistentCloudKitContainerOptionsKey = "<NSPersistentCloudKitContainerOptions: …Run Code Online (Sandbox Code Playgroud) cloudkit ×10
core-data ×6
swift ×4
icloud ×3
ios ×2
nspersistentcloudkitcontainer ×2
swiftui ×2
apple-watch ×1
integration ×1
ios15 ×1
watchkit ×1
watchos ×1
watchos-7 ×1
widgetkit ×1