CloudKit 不发送更新通知
Posted
技术标签:
【中文标题】CloudKit 不发送更新通知【英文标题】:CloudKit Not Sending Update Notifications 【发布时间】:2016-10-07 08:04:31 【问题描述】:我正在尝试开发一个简单的消息应用程序来学习 CloudKit 的基础知识。
我已经差不多搞定了,只是我无法接收记录更新事件的通知。
为了测试应用程序,我在设备和模拟器上同时运行它。
两个实例都登录到同一个 iCloud 帐户(还没有创建专用帐户进行测试...);但是,该应用使用 UUIds 区分本地用户和远程用户,所以这不是问题。
当应用程序的一个实例想要发送消息时,它会创建一条记录并将其保存到 CloudKit。
我知道模拟器不支持 APN,但如果我从模拟器发送消息,我可以在设备上收到通知。
这行得通。
接下来,我想将消息标记为“已读”:也就是说,当它们第一次显示在不是它们的作者的设备上时,标记它们。
我通过获取相应的记录、修改它并保存它来做到这一点。因此,我从设备发送的消息显示在模拟器上,并在那里标记为“已读”。我将更改与 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 吗?我觉得这很难相信,因为“创建”通知交付时没有问题。
两种通知(“消息创建”和“消息更新”)的订阅都已成功注册,并显示在 CloudKit 仪表板上(触发器 INSERT
和 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
...而“更新”订阅没有:
let notificationInfo = CKNotificationInfo()
subscription.notificationInfo = notificationInfo
添加警报正文后,“更新”通知开始到达。
但是,这只是一种解决方法:我需要 静默 通知我的阅读更新。显示横幅只是为了提醒用户他的消息已在另一端阅读是没有意义的。 另外,CloudKit 编程指南也没有提到这个限制。
有没有办法订阅静默(即空)推送通知?
更新 2: 实际上,我在 API Reference 上为 CKNotificationInfo
找到了这个位:
注意
如果您未设置任何
alertBody
、soundName
或shouldBadge
属性,推送通知以较低的优先级发送 不会导致系统提醒用户。
(强调我的)
我仍然看不出这个“不会导致系统提醒用户的较低优先级”如何等同于“application(:didReceiveRemoteNotification:fetchCompletionHandler:)
根本没有被调用”。
【问题讨论】:
你找到解决办法了吗? 并非如此。这是一个爱好项目,从那以后我一直忙于工作。 【参考方案1】:解决方案似乎是使用带有shouldSendContentAvailable = true
的信息对象,如下所示:
let info = CKNotificationInfo()
info.shouldSendContentAvailable = true
subscription.notificationInfo = info
这已经为我解决了。它会导致didReceiveRemoteNotification:
触发,而不会出现任何用户可见的通知。所以它是一个无声的通知,正如所愿,它实际上是如愿到达的。
如果我离开subscription.notificationInfo
nil,则应用程序永远不会收到更改通知。但是使用 [有效沉默] 信息对象,我得到了想要的结果。
【讨论】:
我发现如果我也设置一个空白alertBody
像这样:info.alertBody = ""
,我在后台推送方面的可靠性更高。这有助于以更高的优先级发送推送,但它仍然会以静默方式到达。以上是关于CloudKit 不发送更新通知的主要内容,如果未能解决你的问题,请参考以下文章