CKQueryNotification.recordID: 无法识别的选择器发送到实例
CKQueryNotification.recordID: unrecognized selector sent to instance
我正在尝试设置静默推送通知以使用 CloudKit 跨设备传播本地通知,但我无法理解为什么每次收到远程通知时我的应用程序都会崩溃。
一切正常,直到我尝试处理收到的通知。尝试访问 didReceiveRemoteNotification 中的 CKQueryNotification 对象的 recordID 时发生崩溃。
我正在注册应用程序 didFinishLaunchingWithOptions 中的远程通知。这是代码的其余部分:
在 didRegisterForRemoteNotification 中,我正在为记录类型 CD_Task 创建一个 CKSubscription。
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let subscription = CKQuerySubscription(recordType: "CD_Task", predicate: NSPredicate(format: "TRUEPREDICATE"), options: .firesOnRecordCreation)
let info = CKSubscription.NotificationInfo()
subscription.notificationInfo = info
CKContainer.default().privateCloudDatabase.save(subscription, completionHandler: { subscription, error in
if error == nil {
// Subscription saved successfully
} else {
// Error occurred, handle it
}
})
}
在 DidReceiveRemoteNotification 中,我将一个 CKQueryNotification 对象传递给一个函数来处理从 iCloud 收到的远程通知:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let ckqn = CKQueryNotification(fromRemoteNotificationDictionary: userInfo as! [String:NSObject]) {
self.iCloudHandleNotification(ckqn)
}
}
最后是iCloudHandleNotification函数代码:
func iCloudHandleNotification(_ ckqn: CKQueryNotification) {
switch ckqn.queryNotificationReason {
case .recordCreated:
// This is where it crashes.. when I try to access ckqn.recordID
CKContainer.default().privateCloudDatabase.fetch(withRecordID: ckqn.recordID!) { (record, error) in
if let record = record {
// Handle creating local notif for record
} else if let error = error {
print("Unable to retrieve record: \(error)")
}
}
default:
break
}
}
编辑:
经过调查,我似乎得到了 CKDatabaseNotification 而不是 CKQueryNotification -- 我应该如何指定我想要 CKQueryNotification?
我终于明白了。我正在使用 NSPersistentCloudKitContainer 跨设备同步我的数据。我的订阅正在观察对 NSPersistentCloudKitContainer 创建的记录所做的任何更改,因此每次进行更改时它都会创建一个 CKDatabaseNotification,而不是 CKQueryNotification。由于我正在尝试处理 CKQueryNotification,我的应用程序一直崩溃,因为它找不到 recordID,因此出现错误消息。
为了解决这个问题,我最终在 iCloud 中创建了一个单独的记录(不是 NSPersistentCloudKitContainer 的一部分)并让我的 CKSubscription 观察对该记录的任何更改。
我正在尝试设置静默推送通知以使用 CloudKit 跨设备传播本地通知,但我无法理解为什么每次收到远程通知时我的应用程序都会崩溃。
一切正常,直到我尝试处理收到的通知。尝试访问 didReceiveRemoteNotification 中的 CKQueryNotification 对象的 recordID 时发生崩溃。
我正在注册应用程序 didFinishLaunchingWithOptions 中的远程通知。这是代码的其余部分:
在 didRegisterForRemoteNotification 中,我正在为记录类型 CD_Task 创建一个 CKSubscription。
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let subscription = CKQuerySubscription(recordType: "CD_Task", predicate: NSPredicate(format: "TRUEPREDICATE"), options: .firesOnRecordCreation)
let info = CKSubscription.NotificationInfo()
subscription.notificationInfo = info
CKContainer.default().privateCloudDatabase.save(subscription, completionHandler: { subscription, error in
if error == nil {
// Subscription saved successfully
} else {
// Error occurred, handle it
}
})
}
在 DidReceiveRemoteNotification 中,我将一个 CKQueryNotification 对象传递给一个函数来处理从 iCloud 收到的远程通知:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let ckqn = CKQueryNotification(fromRemoteNotificationDictionary: userInfo as! [String:NSObject]) {
self.iCloudHandleNotification(ckqn)
}
}
最后是iCloudHandleNotification函数代码:
func iCloudHandleNotification(_ ckqn: CKQueryNotification) {
switch ckqn.queryNotificationReason {
case .recordCreated:
// This is where it crashes.. when I try to access ckqn.recordID
CKContainer.default().privateCloudDatabase.fetch(withRecordID: ckqn.recordID!) { (record, error) in
if let record = record {
// Handle creating local notif for record
} else if let error = error {
print("Unable to retrieve record: \(error)")
}
}
default:
break
}
}
编辑:
经过调查,我似乎得到了 CKDatabaseNotification 而不是 CKQueryNotification -- 我应该如何指定我想要 CKQueryNotification?
我终于明白了。我正在使用 NSPersistentCloudKitContainer 跨设备同步我的数据。我的订阅正在观察对 NSPersistentCloudKitContainer 创建的记录所做的任何更改,因此每次进行更改时它都会创建一个 CKDatabaseNotification,而不是 CKQueryNotification。由于我正在尝试处理 CKQueryNotification,我的应用程序一直崩溃,因为它找不到 recordID,因此出现错误消息。
为了解决这个问题,我最终在 iCloud 中创建了一个单独的记录(不是 NSPersistentCloudKitContainer 的一部分)并让我的 CKSubscription 观察对该记录的任何更改。