OneSignal 上的关键警报支持不起作用

Critical Alert support on OneSignal not working

我们在使用 OneSignal 的新 iOS 严重警报功能时遇到问题。我们拥有的应用程序是使用 Apache Flex 构建的,推送通知有效负载从 compiled/generated 到 Distriqt ANE and sent through the OneSignal iOS SDK。我们已获得 Apple 的关键警报批准,但在尝试通过 OneSignal 发送有效负载时,它不起作用。

Distriqt 团队内置了对关键警报的支持,这很好,但是一旦通过 OneSignal 发送,有效负载就不会成功传递,也不会生成关键警报。需要明确的是,一般的推送通知工作正常。

OneSignal documentation on Critical Alerts, though it is over simplified. The payload needed to trigger Critical Alerts on iOS 很清楚,但是无法通过 OneSignal iOS SDK 构建这样的有效负载。

link, we have performed #1 (Update OneSignal App Payload Structure for iOS) but #2 is unclear。有效载荷需要是什么样子的?提供的代码并没有说清楚。此外,引用的 'notification category extension' 是什么?如果识别出该代码,我们此时需要做什么?

我们已经联系了 OneSignal,但未能成功了解如何成功构建此有效负载。文档说 'iOS features OneSignal SDK supports' 但从他们的支持我们收到了这个:

Unfortunately our SDK is not setup to handle critical alerts.

One user reported he achieved this with our additional data parameter like this:

"data": {"CRITICAL_ALERT":"YES","CRITICAL_PAYLOAD":{"CRITICAL_VOLUME":"1.0","CRITICAL_SOUND":"Alert.wav"}}

尽管那行不通。虽然这是一个相对较新的功能,但我希望社区中的某些人在这方面取得了成功并且可以提供帮助。谢谢!

TL;DR 构建 iOS 通知服务扩展是解决方案。 The OneSignal documentation mentions this 但细节少得多。


当 Apple 引入关键警报时,他们更改了通过 APNS 负载传递的 sound 参数。以前,sound 只是一个字符串。例如:

{ 
    “aps” : { 
        “sound” : “critical-alert-sound.wav”
    }
}

对于严重警报,它是一本字典。示例:

{ 
    “aps” : { 
        “sound” : { 
            “critical”: 1, 
            “name”: “critical-alert-sound.wav”, 
            “volume”: 1.0 
        } 
    }
}

字符串版本仍然有效,用于非关键警报。根据推断和测试,将sound参数传递给OneSignal时,仅支持初始'string'版本。当 OneSignal 将有效负载发送给 Apple 时,它​​会将其作为字符串传递,因此即使尝试将声音字典传递给 OneSignal 也无法正常工作,因为它在到达 Apple 之前会被解析。当 Apple 与您的设备进行通信时,词典已经消失,从而阻止设备将其识别为严重警报。

这就是 Notification Service Extension 的用武之地。来自 Apple 的文档:

A UNNotificationServiceExtension object provides the entry point for a Notification Service app extension, which lets you customize the content of a remote notification before it is delivered to the user. A Notification Service app extension doesn't present any UI of its own. Instead, it is launched on demand when a notification of the appropriate type is delivered to the user’s device. You use this extension to modify the notification’s content or download content related to the extension.

简而言之,您可以拦截来自 Apple 的通知 JSON 负载,并在用户看到它之前对其进行修改。


为了将信息从 OneSignal->Apple->Device 正确传递到设备,您需要:

1) 将您的 OneSignal 帐户上的 additional_data_is_root_payload 值设置为 true。为此,这是通过 Update an App API call on OneSignal. I used Postman 完成的。需要明确的是,这需要完成一次,而不是每次发出通知 API 调用时都需要重复的事情。

2) 在您的 OneSignal API 负载中,将 mutable_content 参数设置为 true

如上所述,您可以在有效负载的 OneSignal data 参数中使用值。 data 有效负载是一个开放字段,可用于您想要通过 OneSignal->Apple->Device 流程传递的任何其他信息,并且确实会传送到 device/app 然后您可以对其进行解析你想要。在我的示例中,我们使用:

"data": {"CRITICAL_ALERT":"YES"}

数据负载是任意的,它只需要匹配您在通知服务扩展中所做的检查。


然后我们在 XCode 中创建我们的通知服务扩展。 There are some great step-by-step instructions here on creating an extension。这是通过 XCode 完成的,因此如果您正在构建本机应用程序,只需通过您的应用程序的 XCode 项目即可完成。如果您使用的是像 Adob​​e AIR 这样的框架,它会稍微复杂一些,我将在另一个 post 中详细介绍。请记住,通知服务扩展基本上是一个单独的 'app' 与父应用程序捆绑在一起。它被编译成一个扩展名为 'appex' 的文件,即使它是一个单独捆绑的二进制文件,它也是专门针对您的父应用程序的。

创建扩展后,您的 XCode 项目将有一个名为 NotificationService.swift 的文件,其中包含 class,其中包含 didReceive 方法。然后我们添加了这段代码:

self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

if let bestAttemptContent = bestAttemptContent {

// Modify the notification content here...
    if ((request.content.userInfo["CRITICAL_ALERT"] as? String) == "YES"){
            bestAttemptContent.sound = UNNotificationSound.defaultCriticalSound(withAudioVolume: 1.0)
    }

    contentHandler(bestAttemptContent)
}

您可以看到我们检查了数据负载 (request.content.userInfo) 以查看 CRITICAL_ALERT 键是否设置了值 YES。如果是这样,我们将 'critical sound' 添加到通知中,从而有效地将其变成严重警报。在这种情况下,我们使用 defaultCriticalSound 函数保持简单,但如果您想定义自己的声音,也可以使用 criticalSoundNamed。如果您想为特定通知创建特定声音,您还可以通过数据负载传递要用于警报的声音,然后解析它并将其添加到通知服务扩展中。


此时,一旦我们将应用程序部署到我们的设备,我们就通过 OneSignal 界面对此进行了测试。这可以通过登录您的 OneSignal 帐户然后转到 'Messages' -> 'New Push' 并选择您要将推送发送到的设备来访问:

希望这对其他使用 OneSignal 进行严重警报的人有所帮助(并希望他们尽快更新系统,不再需要通知服务扩展)。