ios - APNS 严重警报被视为正常通知

标签 ios json swift firebase-cloud-messaging apple-push-notifications

我正在尝试通过 FCM 将严重警报从 PHP 后端发送到我的 iOS 应用程序。问题是,通知不会被视为严重警报,也不会绕过“请勿打扰”模式。

从后端发送到 FCM 的负载(示例)

{
    "to": "<fcm token>",
    "data": {"property-1": "value-1"},
    "priority": "high",
    "notification": {
        "title": "Hello World!",
        "body": "Lorem Ipsum ...",
        "badge": 1
        "sound": {
            "critical": 1,
            "name": "default",
            "volume": 1.0
        },
        "color": "#ffffff"
    },"time_to_live": 300,
    "content_available": true
}

根据Apple documentation这种格式应该是有效的。

在设置中启用了严重警报。

到目前为止我发现的唯一可疑的事情是保存推送通知信息的userInfo变量将sound保存为JSON字符串而不是序列化的对象。

Printing description of userInfo:
▿ 4 elements
  ▿ 0 : 2 elements
    ▿ key : AnyHashable("gcm.message_id")
      - value : "gcm.message_id"
    - value : <message-id>
  ▿ 1 : 2 elements
    ▿ key : AnyHashable("google.c.a.e")
      - value : "google.c.a.e"
    - value : 1
  ▿ 2 : 2 elements
    ▿ key : AnyHashable("aps")
      - value : "aps"
    ▿ value : 4 elements
      ▿ 0 : 2 elements
        - key : content-available
        - value : 1
      ▿ 1 : 2 elements
        - key : alert
        ▿ value : 2 elements
          ▿ 0 : 2 elements
            - key : title
            - value : Hello World!
          ▿ 1 : 2 elements
            - key : body
            - value : Lorem Ipsum ...
      ▿ 2 : 2 elements
        - key : badge
        - value : 1
      ▿ 3 : 2 elements
        - key : sound
        - value : {"volume":1.0,"critical":1,"name":"default"}
  ▿ 3 : 2 elements
    ▿ key : AnyHashable("message")
      - value : "message"
    - value : {"data":...}

这是 iOS 或 APNS 中的错误吗?

{"volume":1.0,"critical":1,"name":"default"}

有什么想法可以让它发挥作用吗?

最佳答案

严重警报

首先,关于Apple Push Notification Service的一些信息。

来自 Apple 文档:criticalAlertSetting :

When UNNotificationSetting.enabled, this property authorizes the app to play critical sounds that ignore Do Not Disturb and the device’s mute switch.

For remote notifications, the system attempts to play a critical sound when the notification’s payload contains a sound directory that contains the critical key. Critical alerts require a special entitlement issued by Apple.

来自 Apple 文档:UNNotificationContent :

Don't create instances of this class directly. For remote notifications, the contents of this object are derived from the JSON payload that your server sends to the APNS server.

UNNotificationContent 有几个属性:

var title: String // A short description of the reason for the alert.
var subtitle: String // A secondary description of the reason for the alert.
var body: String // The message displayed in the notification alert.
var badge: NSNumber? // The number to display as the app’s icon badge.
var sound: UNNotificationSound? // The sound to play when the notification is delivered.
var launchImageName: String // The name of the launch image to display when your app is launched in response to the notification
var userInfo: [AnyHashable : Any] // A dictionary of custom information associated with the notification.
var attachments: [UNNotificationAttachment] // An array of attachments to display with the notification.

请注意,sound 属性和 userInfo 属性是分开的。这意味着关键警报设置必须存储在 sound 下,而不是 userInfo 下。


Firebase 云消息传递 (FCM)

以前,Firebase 云消息传递 (FCM) 不支持关键警报,必须直接使用 Apple 推送通知服务 (APNS) 来完成。但是,据我所知,FCM API 现在为此提供了一个 sound 属性。


重要的两点:

1:你必须有一个 critical alerts entitlement从 Apple 获得此功能。你必须证明为什么你的应用程序应该被允许绕过用户偏好来提供通知,即使在“请勿打扰”打开的情况下也是如此。然后,您必须在 Xcode 中用这个更新您的配置文件。

2:在请求通知权限时,您还必须专门请求关键警报的权限:

var authOptions: UNAuthorizationOptions?
if #available(iOS 12.0, *) {
    authOptions = [.alert, .badge, .sound, **.criticalAlert**]
} else {
    authOptions = [.alert, .badge, .sound]
}
UNUserNotificationCenter.current().requestAuthorization(options:   
  authOptions!) { (granted, error) in
    // Handle outcome here
}

然后将提示用户明确允许关键通知。


总而言之,使用较新版本的 FCM 应该可以做到这一点,但如果实现了上述步骤,则肯定可以使用 native APNS。

您可能还想查看 this answer了解一种使用通知扩展在收到警报时使警报变得关键的方法。 mutable-content 键必须设置为 true,以便调用通知扩展。

关于ios - APNS 严重警报被视为正常通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58983109/

相关文章:

ios - AVPlayer 键值的 currentItem 是否可观察?

ios - 如何将 UIImageView 限制为最佳尺寸?

c# - Nancy FX 在模型绑定(bind)上将字典中的键大写

c# - (不?)使用 JavaScriptSerializer 将 xml 文件(未知模式)转换为 c# 中的 json

objective-c - Objective C 中的 Sprite.Frame.Contains 吗?

ios - 无法获得 supportedInterfaceOrientationsForWindow 以使用 Swift 1.2

android - 无法提取国家/地区的OpenWeather

ios - 如何将旧项目移动到PersistentContainer

json - GDBM 与简单的 JSON、INI 或 YAML 配置文件

swift - 创建一类颜色