CloudKit 通知的动态 alertBody

Posted

技术标签:

【中文标题】CloudKit 通知的动态 alertBody【英文标题】:Dynamic alertBody for CloudKit notifications 【发布时间】:2020-09-16 12:11:08 【问题描述】:

我正在尝试使用 CloudKit 向订阅了发布剧集的频道的用户发送推送通知。我可以创建CKRecord,订阅用户,并在新剧集发布时收到通知,尽管我希望我的alertBody 成为新发布的剧集的标题。

现在推送通知显示用于保存订阅的原始CKRecordalertBody

我读过有人解释如何使用 Localization.Strings 文件,但不知道这对我有什么帮助。 CloudKit 甚至可以做到这一点吗?

static func registerSubscriptionWith(ID: String) 
    let predicate = NSPredicate(format: "channelID == %@", ID)
    let subscription = CKQuerySubscription(recordType: "Episode", predicate: predicate, options: .firesOnRecordCreation)
    
    let myContainer = CKContainer.default()
    let publicDatabase = myContainer.publicCloudDatabase
    
    let recordID = CKRecord.ID(recordName: ID)
    publicDatabase.fetch(withRecordID: recordID)  (record, error) in
        if let error = error 
            print("Error: \(error.localizedDescription)")
         else 
            if record != nil 
                let notification = CKSubscription.NotificationInfo()
                notification.title = record!["channelName"]
                notification.alertBody = record!["caption"]
                notification.soundName = "default"
                
                subscription.notificationInfo = notification
                
                publicDatabase.save(subscription)  result, error in
                    if error != nil 
                        print(error!.localizedDescription)
                     else 
                        print("Success subscribing user to episode notifications")
                    
                
                
            
        
    

【问题讨论】:

那你为什么不使用 notification.alertBody = NSLocalizedDescription(record!["caption"]) ? 嘿@Chris,请告诉我如何实现它。你的意思是NSLocalizedDescriptionKey?此外,您还添加了记录对象。订阅用户时,我应该保持publicDatabase.fetch 的这种配置方式吗?添加您的行时出现错误。 【参考方案1】:

是的,这绝对是可能的。

== 第 1 步 ==

在 Xcode 项目的 /Resources 文件夹中创建一个 Localizable.strings 文件并将其放入其中:

"%1$@" = "%1$@";

== 第 2 步 ==

CKSubscriptions.NotificationInfo() 添加更多详细信息,如下所示:

let info = CKSubscription.NotificationInfo()
  
//Notification Title
info.titleLocalizationKey = "%1$@"
info.titleLocalizationArgs = ["title"] //Matches a CKRecord field on your Episode recordType

//Notification Subtitle (Optional)
info.subtitleLocalizationKey = "%1$@"
info.subtitleLocalizationArgs = ["subtitle"] //Matches a CKRecord field

//Notification Body/Message
info.alertLocalizationKey = "%1$@"
info.alertLocalizationArgs = ["details"] //Matches a CKRecord field

//One key for each of the above to fetch
info.desiredKeys = ["title", "subtitle", "details"]

//Always set this to true
info.shouldSendContentAvailable = true

//More Notification Options
info.shouldBadge = false
info.soundName = "Notification.wav"

subscription.notificationInfo = info

如果您的Episode 记录类型没有titlesubtitledetails,您可能需要在其上添加额外的字段来显示您希望在通知中显示的确切文本。

【讨论】:

虽然其他建议可能适用于更多信息,但它开箱即用,尽管它仍然有点神秘。例如,我的字段是“channelName”和“caption”。通知如何知道哪个是标题可以正文?是期望键的顺序吗?如何从 URL 添加图片? 哦,我看到键不一样了,抱歉,这是我的阅读障碍。仍然对图像感到困惑。 我从未尝试将图像添加到推送通知中,所以我不熟悉,抱歉。【参考方案2】:

实现此目的的一种方法是订阅 Episode 上的记录更改,例如为频道 ID 创建新剧集时

let subscription = CKQuerySubscription(
     recordType: "Episode",
     predicate: NSPredicate(format: "channelID == %@", ID),
     subscriptionID: CKQuerySubscription.ID("episode_subscription"),
     options: [
        CKQuerySubscription.Options.firesOnRecordCreation,
     ]
 )

将订阅保存到数据库

let info = CKSubscription.NotificationInfo()
info.shouldSendContentAvailable = true
subscription.notificationInfo = info
        
let operation = CKModifySubscriptionsOperation(
   subscriptionsToSave: [subscription],
   subscriptionIDsToDelete: nil
)

最后一步是在AppDelegate 中处理didReceiveRemoteNotification 中的通知

if let dict = userInfo as? [String: NSObject] 
   if let notification = CKNotification(fromRemoteNotificationDictionary: dict) 
     if let queryNotification = notification as? CKQueryNotification  
       //Fetch record with id
       let operation = CKFetchRecordsOperation(recordIDs:[queryNotification.recordID])
       ...
       //Show notification when fetch is completed.
     
       

【讨论】:

谢谢,我愿意试一试,但是当您说“提取完成时显示通知”时,您的意思是现在将其显示为本地通知吗?我不确定如何从操作中返回的记录中更改通知内容并“显示”。谷歌搜索只是解释如何以这种方式显示本地通知。

以上是关于CloudKit 通知的动态 alertBody的主要内容,如果未能解决你的问题,请参考以下文章

未收到来自 CloudKit 订阅的推送通知

CloudKit 向其他用户推送通知

Cloudkit 新记录通知

使用 CloudKit 延迟后触发推送通知

CloudKit 通知未发送到所有设备

如何使用 CloudKit 的通知传递数据?