我正在尝试设置静默推送通知,以使用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?
为了解决这个问题,我最终在iCloud中创建了一个单独的记录(不是NSPersistentCloudKitContainer的一部分),并使CKSubscription观察到对该记录的任何更改。