我在两台不同的设备上有两个 icloud 帐户(A 和 B)。我从其中一个 (A) 将 ckrecord 共享给另一个 (B),如下所示:
let controller = UICloudSharingController { controller, preparationCompletionHandler in
let share = CKShare(rootRecord: record)
share[CKShareTitleKey] = "title" as CKRecordValue
share[CKShareTypeKey] = "pl.blueworld.fieldservice" as CKRecordValue
share.publicPermission = .readWrite
let modifyOperation = CKModifyRecordsOperation(recordsToSave: [record, share], recordIDsToDelete: nil)
modifyOperation.savePolicy = .ifServerRecordUnchanged
modifyOperation.perRecordCompletionBlock = { record, error in
print(error?.localizedDescription ?? "")
}
modifyOperation.modifyRecordsCompletionBlock = { records, recordIds, error in
print(share.url)
preparationCompletionHandler(share, CloudAssistant.shared.container, error)
}
CloudAssistant.shared.container.privateCloudDatabase.add(modifyOperation)
}
controller.delegate = self
UIViewController.top()?.present(controller, animated: true)
当第二个设备 (B) 接受 cloudkit 共享时,我获取记录并订阅更改:
func application(_ application: UIApplication, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShareMetadata) {
let acceptSharesOperation = CKAcceptSharesOperation(shareMetadatas: [cloudKitShareMetadata])
acceptSharesOperation.perShareCompletionBlock = { metadata, share, error in
if let error = error {
UIAlertController.show(withMessage: error.localizedDescription)
} else {
let operation = CKFetchRecordsOperation(recordIDs: [cloudKitShareMetadata.rootRecordID])
operation.perRecordCompletionBlock = { record, _, error in
if let error = error {
UIAlertController.show(withMessage: error.localizedDescription)
} else if let record = record {
CloudAssistant.shared.save(records: [record], recordIDsToDelete: [])
let options: CKQuerySubscriptionOptions = [.firesOnRecordCreation, .firesOnRecordUpdate, .firesOnRecordDeletion]
let territorySubscription = CKQuerySubscription(recordType: "Territory", predicate: NSPredicate(value: true), options: options)
let notificationInfo = CKNotificationInfo()
notificationInfo.shouldBadge = false
notificationInfo.shouldSendContentAvailable = true
territorySubscription.notificationInfo = notificationInfo
CloudAssistant.shared.sharedDatabase?.save(territorySubscription) { _, _ in }
}
}
CloudAssistant.shared.container.sharedCloudDatabase.add(operation)
}
}
acceptSharesOperation.qualityOfService = .userInteractive
CKContainer(identifier: cloudKitShareMetadata.containerIdentifier).add(acceptSharesOperation)
}
现在从设备 A 我成功(我确信,更改保存在 iCloud 中)对与他人共享的记录执行更新。但是设备B并不知道,除非我再次手动获取记录。
但从另一方面来看,它的效果还不错。
如果我成功地对与我共享的记录执行了更新(在设备 B 上),那么设备 A 会神奇地收到有关更改的通知,一切都很好。有什么区别?
如何订阅与我共享的记录的更改?
P.S 当我有能力时,我会为愿意帮助我的人提供 200 甚至更多的赏金。
iOS 11、 swift 4、Xcode 9
最佳答案
这是我的 list ,用于调试未按预期出现的订阅通知。听起来您可能已经排除了其中一些。
- 确保该应用已注册接收通知
- 确保在设备上为此应用启用了通知
- 确保所有设备都使用相同的容器
- 在下次应用启动时,使用
fetchAllSubscriptionsWithCompletionHandler
和 NSLog 读取所有订阅,了解每个订阅的详细信息(特别是:订阅 ID、触发器选项、记录类型和谓词)。验证预期的潜艇是否存在。验证每个子的谓词是否符合预期(在这种情况下,比较您在两个设备上找到的谓词)。
在以下情况下,我浪费了大量时间来调试“缺失”通知:
- 我的本地构建版本使用的是 TEST 环境,而 TestFlight 用户访问的是 PROD 环境。调试步骤 2 发现了这一点。
- 当无意中重复使用订阅 ID 时,每个新的订阅 ID 都会覆盖之前的订阅 ID。调试第4步最终发现问题
到目前为止,这四个调试步骤已经帮助我理解了我所有的“丢失通知”问题。一旦我理解了为什么没有出现通知,就缩小了负责的代码块的范围。
关于ios - 如何接收有关与我共享的记录更改的 cloudkit 通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46784052/