Swift - 如何在后台和前台获得某些无声通知?

Posted

技术标签:

【中文标题】Swift - 如何在后台和前台获得某些无声通知?【英文标题】:Swift -How to get certain silent notifications in the background and others in the foreground? 【发布时间】:2019-07-16 16:25:10 【问题描述】:

在我的应用中,用户可以互相发送聊天消息并下订单(类似于 OfferUp)。我使用静默推送通知,我可以毫无问题地收到它们。

我想要做的是,当用户A 向用户B 发送订单时,无论用户B 是在background 还是foreground,都会收到一个静默通知。

但是当 userA 向 userB 发送消息时,只有当 userB 位于 background 中时,才应该通过静默通知。如果 userB 在前台,则不需要通知。

我将orderId 用于订单,messageId 用于消息。

我在App Delegate's 收到静默通知:

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) 

    let userInfo = notification.request.content.userInfo

    // I can parse userInfo and get the messageId or the orderId

    guard let userInfo = userInfo as? [String: Any] else  return 

    if let orderId = userInfo["orderId"] as? String 
    

    if let messageId = userInfo["messageId"] as? String 
    

OrderVC:

func orderWasPlacedNowSendNotification() 

    let urlString = "https://fcm.googleapis.com/fcm/send"

    var apsDict = [String: Any]()
    apsDict.updateValue(title, forKey: "title")
    apsDict.updateValue(body, forKey: "body")
    apsDict.updateValue(1, forKey: "content-available")

    var dataDict = [String: Any]()
    dataDict.updateValue(orderId, forKey: "orderId") // orderId

    var paramDict = [String: Any]()
    paramDict.updateValue(apsDict, forKey: "notification")
    paramDict.updateValue(toToken, forKey: "to")

    paramDict.updateValue(dataDict, forKey: "data")

    let request = NSMutableURLRequest(url: url as URL)
    URLSession.shared.dataTask(with: request as URLRequest) ...

消息VC:

func messageWasSentNowSendNotification() 

    let urlString = "https://fcm.googleapis.com/fcm/send"

    var apsDict = [String: Any]()
    apsDict.updateValue(title, forKey: "title")
    apsDict.updateValue(body, forKey: "body")
    apsDict.updateValue(1, forKey: "content-available")

    var dataDict = [String: Any]()
    dataDict.updateValue(messageId, forKey: "messageId") // messageId

    var paramDict = [String: Any]()
    paramDict.updateValue(apsDict, forKey: "notification")
    paramDict.updateValue(toToken, forKey: "to")

    paramDict.updateValue(dataDict, forKey: "data")

    let request = NSMutableURLRequest(url: url as URL)
    URLSession.shared.dataTask(with: request as URLRequest) ...

如何分离无声通知?

【问题讨论】:

【参考方案1】:

根据你的逻辑你需要在willPresent里面返回

if application.applicationState == .active    
    completionHandler([])  // no alert/sound

else if application.applicationState == .background   
     completionHandler([.sound,.alert]) // alert with sound
 

您可以根据需要添加更多检查,但最后分别返回 slient/alert 的任何完成

【讨论】:

谢谢,成功了!我不得不使用 UIApplication.shared.applicationState

以上是关于Swift - 如何在后台和前台获得某些无声通知?的主要内容,如果未能解决你的问题,请参考以下文章

当应用程序进入后台和前台时,带有通知中心的登录屏幕,Swift

接收后台通知iOS Swift 5(无正文和标题)

如何在后台和前台处理 Firebase 通知?

cordova 如何在前台和后台划分通知回调?

当应用程序使用 Swift 在前台运行时显示推送通知

android 如何实现后台时用通知栏显示有新的消息,当在前台时不显示通知