iOS critical alert through FCM

2019-06-14 06:46发布

问题:

iOS 12 has added critical alerts. The APNS payload has the sound dictionary to support critical alerts. Is there an equivalent sound dictionary support in FCM payload to send FCM notifications to iOS devices.

回答1:

There is currently no sound dictionary support in FCM which is equivalent to iOS' sound dictionary. As I'm sure you're already aware of, the counterpart of FCM with APNs' when it comes to sound is the sound parameter:

The sound to play when the device receives the notification.

Sound files can be in the main bundle of the client app or in the Library/Sounds folder of the app's data container. See the iOS Developer Library for more information.

However, reading from the UNNotificationSound docs, maybe you could try adding a data message payload that contains an identifier (e.g. "isCritical": "true") then have your app handle it as needed.



回答2:

Answering my own question.

I had to rely on notification extension to do the magic as the FCM payload doesn't support the iOS sound dictionary. I send the "critical" flag set to 1 as part of FCM data payload and use it in notification extension to mark a notification as critical.

class NotificationService: UNNotificationServiceExtension {
    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
       self.contentHandler = contentHandler
       bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
       let userInfo: [AnyHashable : Any] = (bestAttemptContent?.userInfo)!
       if let apsInfo = userInfo["aps"] as? [AnyHashable: Any], let bestAttemptContent = bestAttemptContent, let critical =  userInfo["critical"] as? String, Int(critical)! == 1 {
            //critical alert try to change the sound if sound file is sent in notificaiton.
            if let sound = apsInfo["sound"] as? String {
                //sound file is present in notification. use it for critical alert..
                bestAttemptContent.sound =
                    UNNotificationSound.criticalSoundNamed(UNNotificationSoundName.init(sound),
                                                           withAudioVolume: 1.0)
            } else {
                //sound file not present in notifiation. use the default sound.
                bestAttemptContent.sound =
                                UNNotificationSound.defaultCriticalSound(withAudioVolume: 1.0)
            }
            contentHandler(bestAttemptContent)
        }
    }
}