我正在尝试开发一个简单的消息传递应用程序来学习CloudKit的基础知识。
我几乎弄清楚了,除非我无法收到记录更新事件的通知。
要测试应用程序,我会在设备和模拟器上同时运行它。
这两个实例都登录到同一个iCloud帐户(没有为创建专用帐户进行测试......);然而,该应用程序使用UUIds区分本地用户和远程用户,因此这不是问题。
当应用程序的一个实例想要发送消息时,它会创建一条记录并将其保存到CloudKit。
我知道模拟器上不支持APN,但如果我从模拟器发送消息,我可以在设备上收到通知。
这样做。
下一步,我想将消息标记为" read":也就是说,当它们首次显示在不是创作它们的设备上时,标记它们。
我这样做是通过获取相应的记录,修改它并保存它。因此,我从设备发送的消息显示在模拟器上,并在那里标记为“读取”。我将此更改与cloudKit同步,希望设备收到通知:
publicDatabase.perform(query, inZoneWith: nil, completionHandler: {(records, error) in
guard let records = records, records.count > 0 else {
return print("Error - Message: \(message.text) by \(message.userName) NOT found on the cloud!")
}
let record = records[0]
// HERE THE RECORD IS MODIFIED LOCALLY:
record["readTimestamp"] = (message.readTimestamp! as NSDate)
// Now, save it:
self.publicDatabase.save(record, completionHandler: {record, error in
guard error == nil else {
return print("Error - Message: \(message.text) by \(message.userName) could NOT be saved as read!")
}
print("Message: \(message.text) by \(message.userName) SAVED as read at \(message.readTimestamp!)")
})
})
然而,另一方面,'更新'永远不会收到通知。
是否因为两个实例都以同一个用户身份登录到iCloud?我发现很难相信,因为"创造"通知没有问题。
两个通知的订阅("消息创建"和#34;消息更新")已成功注册并显示在CloudKit仪表板上(触发INSERT
和{{1} })。
更新:经过很长一段时间思考我的"创建"之间可能存在什么不同?订阅和我的更新"订阅只能导致其中一个人发出通知,我意识到只有"创建"订阅有一个通知机构:
UPDATE
...而"更新"订阅没有:
let subscription = CKQuerySubscription(recordType: "Message",
predicate: NSPredicate(value: true),
subscriptionID: Bundle.main.bundleIdentifier! + ".subscription.message.create",
options: .firesOnRecordCreation
)
let notificationInfo = CKNotificationInfo()
// THIS LINE MAKES ALL THE DIFFERENCE:
notificationInfo.alertBody = "You've Got Mail!"
subscription.notificationInfo = notificationInfo
publicDatabase.save(subscription, completionHandler: {savedSubscription, error in
一旦我添加了一个警报正文,"更新"通知开始到来。
但是,这只是一种解决方法:我的读取更新需要无声通知。显示横幅只是为了提醒用户他的消息已在另一端被读取,这是没有意义的。 此外,CloudKit编程指南未提及此限制。
有没有办法订阅静音(即空)推送通知?
更新2:实际上,我在 let notificationInfo = CKNotificationInfo()
subscription.notificationInfo = notificationInfo
的{{3}}上找到了这一位:
注意
如果您未设置任何
CKNotificationInfo
,alertBody
或soundName
属性,推送通知以 较低优先级 发送 不会导致系统提醒用户。
(强调我的)
我仍然没有看到这个"较低的优先级如何不会导致系统提醒用户"相当于" shouldBadge
根本没有被调用"。
答案 0 :(得分:2)
解决方案似乎是使用if="${vm.personal}
的信息对象,如下所示:
shouldSendContentAvailable = true
这已经为我解决了。它会导致let info = CKNotificationInfo()
info.shouldSendContentAvailable = true
subscription.notificationInfo = info
触发,而不会显示任何用户可见通知。因此,根据需要,它是一个无声的通知,它实际上是按照需要到达的。
如果我将didReceiveRemoteNotification:
保留为零,则不会通知应用程序更改。但是使用[有效静默]信息对象,我得到了理想的结果。