一个应用程序中的多个通知服务扩展

Multiple Notification Service Extension in one app

是否可以在一个应用程序中添加多个通知服务扩展?如果是,那么如何识别将使用哪个以及如何识别?

基本上我的应用程序有两个服务提供商,它们都有自己的通知服务扩展负载,所以有什么方法可以添加两个不同的通知服务扩展,并根据 serviceProvider = 负载中的值= "1" 我可以告诉应用 运行 serviceProvider 1

的扩展

NotificationServiceExtension

文档对此没有任何说明。在我的测试中,它不起作用。所有通知都通过单个 NotificationServiceExtension.

处理

NotificationContentExtension

对于 NotificationContentExtension,文档说:

You may add more than one notification content app extension to your project, but each one must support a unique set of notification categories. You specify the categories for your app extension in its Info.plist file, as described in Declare the Supported Notification Types.

Customizing the Appearance of Notifications docs

我验证了☝️并且成功了! FWIW 您可以对多个类别使用单个通知内容扩展。

UNNotificationExtensionCategory (Required)

A string or an array of strings. Each string contains the identifier of a category declared by the app using the UNNotificationCategory class.

另外值得一提的是,NotificationServiceExtension 的默认 plist 设置如下所示:

它没有将自己与任何给定类别相关联。我尝试添加 NSExtensionAttributes 以及 UNNotificationCategoryExtension 键值。但是即使它编译了,它也没有用!我认为 Apple 决定如何使用通知服务扩展的方式基于这两个字段:

  • 一个目标,其 bundleID 的前缀为 apns-topic
  • 必须始终设置为 com.apple.usernotifications.serviceNSExtensionPointIdentifer 字段。对于今天的扩展或内容通知扩展等,此值不同

因此,如果您有两个服务扩展,那么系统无法决定应该显示哪一个

但是 NotificationContentExtension 的默认 plist 设置确实有 UNNotificationCategoryExtension 键,包括值:


还要考虑更多,如果一个应用程序有 5 个不同的类别,并且每个类别都有一个服务扩展并同时接收所有类别,那么它将启动 5 个不同的进程(想想 5 个并行 didFinishLaunchingWithOptions 回调。每个类别和流程一个),这对 OS.

不利

虽然不确定,但 documentation on Signal's NotificationService class 支持这一理论。

// Note that the NSE does *not* always spawn a new process to
// handle a new notification and will also try and process notifications
// in parallel. `didReceive` could be called twice for the same process,
// but will always be called on different threads. To deal with this we
// ensure that we only do setup *once* per process and we dispatch to
// the main queue to make sure the calls to the message fetcher job
// run serially.

NotificationContentExtension 并非如此。它不能一次处理 5 个 contentExtensions。因为它是一个 UI 功能,由主线程门控。