iOS中都有哪些不同类型的通知以及如何正确配置它们?
Posted
技术标签:
【中文标题】iOS中都有哪些不同类型的通知以及如何正确配置它们?【英文标题】:What are different types of notifications in iOS and how to configure them correctly?iOS中有哪些不同类型的通知以及如何正确配置它们? 【发布时间】:2017-02-16 13:15:25 【问题描述】:当我阅读Apple Docs 时,他们提到了 3 种通知类型:本地、远程和静默。
本地通知可以从它的名字中推断出来,它是由应用在本地发送的。
但是,其他两种类型有什么区别呢?
【问题讨论】:
注意:Apple 文档已将 silent 通知重命名为 background 通知! 我相信这个问题的标题应该改为“ios 中有哪些不同类型的通知以及如何正确配置它们?” 【参考方案1】:编辑:虽然此答案完全适用,但 iOS 12 中的通知有一些添加(未更改)。我强烈建议观看 WWDC 2018: What’s New in User Notifications 并阅读 @ 987654322@.
主要变化是:
带有摘要格式的分组通知 临时通知,即未经用户许可直接在通知中心显示通知 忽略“请勿打扰”或“静音”的重要通知 能够与扩展中的通知进行交互 能够完全重置或更新操作 能够从手机的通知中心深层链接到应用的通知设置重要提示:不知道从什么时候开始,但根据 Apple 文档,“静默通知”已重命名为“后台通知”
有太多设置需要正确设置才能正常工作。我会尝试剖析它们,让它们更容易理解。
总的来说,有几件事很重要。
静默和用户通知之间的总体区别 不同类型的用户通知 如何从您的服务器配置远程通知,即 有效负载 如何在项目的后台模式下启用推送通知和远程通知 如何为 remote 和 silent 通知和 APNs 架构向 APNs 注册您的令牌 如何为用户通知请求权限 从设备启用“后台应用刷新”和“通知” 什么是content-available
了解在接收远程通知时,iOS 是您应用的上游
当应用程序已被用户终止时操作系统收到通知时会发生什么
关于可靠性和 APNs 架构的说明
我强烈建议大家观看:WWDC 2015: What's new in Notifications 的前 7 分钟。从那里,演示者提到有两种主要类型的通知:
静默通知
它们发生在后台,因此您永远不会看到任何警报/徽章/声音。下载的东西你不知道。
iOS 11 错误
见here。 iOS 11 初始版本存在静默通知问题。确保 你有最新版本的测试,否则,它可能没有 工作
用户通知
顾名思义,它与用户有关。也就是说,用户将看到警报/标记或听到声音。它有两种类型。
本地通知
可以通过 3 种不同方式触发本地通知:
UNLocationNotificationTrigger
:
当您靠近沃尔玛商店时,您会看到提醒。
UNTimeIntervalNotificationTrigger
:例如您会每 10 分钟看到一次警报。
UNCalendarNotificationTrigger
喜欢 2017 年 12 月 1 日下午 1:00。
远程通知
它们类似于本地通知,但它们是从服务器触发的,例如包含 From 字段(妈妈)和正文字段(我爱你!)的 WhatsApp 消息。
令牌注册和 APNs 架构:
要接收静默或远程通知,您需要使用以下方式注册令牌:
application.registerForRemoteNotifications()
? 注册不需要用户许可。这使得无声通知变得无缝。见this moment of the WWDC video
默认启用无提示通知。用户不需要 批准您的 - 不授予您的应用使用它们的权限, 您可以直接开始使用它们而无需询问用户 权限。
From WWDC
记住 APN 是由 APN 而非您的服务器提供给您的用户的。因此,您的 iOS 代码必须将此令牌发送到您的服务器。因此服务器可以将给定的设备令牌与用户相关联。当您想要推送给某个用户时,您的服务器只是告诉 APNs 将有效负载发送到特定令牌。重要的是要了解您的服务器和 APN 是两个不同的东西
它的流程是这样的:
-
服务器/提供商向 APNs 发送有效负载
APN 向给定帐户的所有目标设备发送通知。例如您的 iPhone、Mac 都可以接收电子邮件/消息通知。
然后您的 iPhone/Mac 会将该消息传送到应用程序。 APN 不会直接向您的应用发送消息。它将它发送到设备。然后 iOS 将其发送到您的应用。
有关更多信息,请参阅文档 APNs Overview 和 Sending Notification Requests to APNs
为了能够显示徽章/警报/声音,您需要向用户请求权限:
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) (granted, error) in
guard error == nil else
//Display Error.. Handle Error.. etc..
return
if granted
//Do stuff here..
//Register for RemoteNotifications. Your Remote Notifications can display alerts now :)
application.registerForRemoteNotifications()
else
//Handle user denying permissions..
问题:我是否需要为本地通知和远程通知请求一次访问权限?
没有。只需编写上面的 sn-p,它将请求 远程和本地访问。
现在让我们进入棘手的部分:D
Xcode 项目 + iPhone 设置
我是否需要启用某些功能才能接收静默通知?
-
您必须从 Xcode 功能中启用推送通知:
如果您不启用此功能,您的应用将不会收到令牌。如果没有令牌,服务器将无法识别您。
-
要能够从后台下载内容,您需要启用:远程通知后台模式。
要启用backgroundModes,您可以使用您的plist 或Xcode 功能。
无论哪种方式,您都可以这样做的原因是因为 plist 更接近您的代码并且是旧方式,也许它是为了遗留支持。 Xcode 功能是更新、简单的方法。
列表:
Item 0 只是一个 index,它不是字典的键(你通常在 plist 中看到的东西),UIBackgroundModes 是字符串的array
。字符串只能来自UIBackgroundModes Array 中的接受值。
Xcode 功能:
在Xcode后台模式中查看Remote Notification
如下:
如果您不执行上述任何操作,则使用以下命令关闭通知:
将杀死远程和本地通知
然而,如果您确实从 plist 或 Xcode 功能启用后台应用刷新,那么即使关闭了应用的通知,您仍然会收到静默通知!
如果用户想要禁用静默通知,他必须禁用这两个通知并禁用“您的应用/整个系统的后台应用刷新”。 要在您的系统中禁用“后台应用刷新”,您必须这样做:
我为什么要说这些?向您说明,对于用户而言,静默通知和推送通知的设置是不同的,发送它们的限制也不同。 有关更多信息,请参阅 WWDC 视频中的 this moment。见here instead(之前的链接失效了):
默认启用静默通知。
用户不需要批准你不授予权限 您的应用程序使用它们,您无需询问即可开始使用它们 用户的权限。
但静默通知是后台应用程序背后的机制 刷新。
在任何时候您都知道用户可以进入设置并禁用 他们。
所以你不能依赖它们总是可用的。
您不知道用户是否将其关闭,而您没有得到 不再是通知。
这也意味着无声通知会以最好的方式传递 努力。
这意味着当通知到达用户的设备时, 系统会做出一些选择。
它将使用来自设备和用户的不同信号 行为,比如权力或一天中的时间来决定什么时候是好的 是时候发送通知并启动您的应用了。
它可能会尝试节省电池或尝试匹配用户行为 并在用户更有可能使用内容时提供内容。
另见here。
警告:即使您禁用应用后台刷新并禁用允许通知,如果您的应用处于前台,您仍然可以收到静默通知。如果您的应用在后台,则不会交付。
我是否需要启用某些功能才能接收远程通知?
您只需要从您的 Xcode 功能中启用 推送通知:
如果您不启用此功能,您的应用将不会收到令牌。如果没有令牌,服务器将无法识别您。
APNs Payload 结构
很好奇...你能告诉我我的有效载荷应该是什么样子吗?
我强烈建议您查看 Apple§documentation。非常清楚,另见Sending Notification Requests to APNs。基本上平台对 APN 进行 HTTP/2 调用并发送所需的有效负载。发送正确的标头至关重要,否则您的通知不会发送到设备!
谢谢,但你能告诉我重要的部分吗?
uhhmm... 好的,但是你知道这是来自我刚才说的链接:
静默通知只有一个标准:
负载的aps
字典必须包含content-available
键
值为1
。
每个docs您可以发送其他字段
如果有与背景一起出现的用户可见更新 更新,您可以在aps中设置警报、声音或徽章键 字典,视情况而定。
示例负载如下所示:
"aps" :
"content-available" : 1
,
"acme1" : "bar",
"acme2" : 42
acme1、acme2,或者只是一些自定义数据!但是对于aps
键,您必须遵循 Apple 的结构,否则,它将无法正确映射,您将无法正确读取数据。
注意:我尚未对此进行验证,但另一位工程师提到,如果您启用了临时通知,那么为确保发送静默通知,您必须包含一个正文为空的警报字段。例如:
"aps" :
"content-available" : 1,
"alert" :
"body" : "",
,
,
对于用户通知:
您的aps
中需要一个alert
密钥。
举个例子:
"aps" :
"alert" : "You got your emails.",
"badge" : 9,
"sound" : "bingbong.aiff"
,
"acme1" : "bar",
"acme2" : 42
还有一个第三个选项,我将在答案后面进一步讨论。
至于固定的aps
和alert
字典键是什么,请参阅这些Apple docs。
好的,知道了。 content-available
是什么?
非常简单。它只是一个标志,告诉您的应用您需要唤醒并下载一些内容,因为我有内容可供下载!有关详细信息,请参阅此exact moment。
默认情况下不包含content-available
标志,即默认情况下,您发送的通知不会触发application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
或在您的应用程序中执行某些操作。它只会显示通知。如果你想唤醒应用程序(在后台做某事),你需要包含content-available
并将其设置为1
。
§:如果您使用的是 Firebase,您的负载结构和键可能会略有不同。例如,密钥
content-available
被替换为content_available
。有关更多信息,请参阅 Firebase documentation 和 here。
我知道您告诉我,我只能在使用静默通知时将某些内容下载到我的应用程序中,但是有没有办法让我也可以在后台唤醒我的应用程序并为远程通知下载某些内容?
是的,但是类似于静默通知,您还必须将content-available
标志设置为1,这样它就会知道唤醒并下载一些东西。否则,它只会弹出并发出警报/徽章/声音,但不会下载任何内容。
重要提示:
如果您的应用只有静默通知,只需从功能中启用“推送通知”+“远程通知”,并将每个负载的content-available
设置为 1
。
如果您的应用只有远程通知,只需从功能中启用“推送通知”。 content-available
无事可做。
但是,如果您希望通知显示警报/徽章/声音并在后台下载某些内容,则必须同时启用“远程通知”和“推送通知”+ 将 content-available
设置为 1
。
(第三个选项)
"aps" :
"content-available" : 1
"alert" : "You got your emails.",
"badge" : 9,
"sound" : "bingbong.aiff"
,
"acme1" : "bar",
"acme2" : 42
来自 WWDC 视频的This moment 提到了?
引用 Apple 工程师的话:
现在,您可以在一个用户远程通知中,您可以设置相同的 您在静默通知中设置的内容可用标志,并且 让您的应用有时间下载内容或更新 它想要显示的内容,以便用户点击时 在通知上,您的内容可用。用户看到了什么 确实如此。这是一种在用户内部进行静默通知的方法 通知之类的摘要。
通知和 iOS 应用程序生命周期
我对远程通知感到困惑。我想每当我收到通知时,我的应用程序就会在后台激活并下载一些东西。你能解释一下吗?
例如此刻:
您的 iPhone 刚刚收到一条远程通知,其正文为“无发件人”。要接收此信息,WhatsApp ** 不必** 必须在后台运行,即您不需要从 BackgroundModes 启用“远程通知”。即使您的应用程序被强制退出或暂停,您仍然会收到通知,因为进程由操作系统而非 WhatsApp 应用程序管理。但是,如果您希望能够将实际消息或其图像/视频下载到 WhatsApp(这样一旦您的用户打开 WhatsApp,视频就会坐在那里等待用户),那么您需要激活您的应用程序.为此,您需要content-available : 1
并实现application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
。
同样,如果您禁用某个应用的蜂窝数据,您仍会收到其通知。但是,通过点击该通知,用户将无法对该应用发出任何网络请求。他们只能打开应用程序。
或者对于另一个类似的情况,如果您连接的服务器/接入点对 WhatsApp 等具有限制访问权限,它仍然允许您接收 APNs 通知。但是,通过点击该通知,用户将无法对该应用发出任何网络请求。他们只能打开应用程序。
CAVEAT:如果应用程序被用户强制退出,那么当您确实因上述原因收到通知时,您无法采取任何措施将应用程序退出自动终止状态(即使您将content-available
设置为1
)。您的任何委托方法都不会受到影响。 用户必须打开应用程序,然后才能访问您的委托方法。
关于可靠性和 APNs 架构的说明:
虽然通知大量用于向应用传递实际内容,但它们在某种程度上并非旨在向应用传递内容。相反,它们旨在通知用户“嘿,有新东西到了(2b 消息或 50kb 小图像,或 10MB 图像或 2 GB 视频)。如果你喜欢,请打开应用. 顺便说一下,这是其中的一小部分(实际消息本身如果它可以容纳,图像的标题或通知中显示的缩略图,视频的标题或显示的缩略图在视频中”。有关更多信息,请参阅iOS APNs “best-effort” fallback。再说一遍,您永远不会下载电子邮件中发送的 40MB 附件。您只会收到它存在的通知。您发送的内容足够多(附件的缩略图视图),以便用户被告知什么是新的,并且可以决定他们是否需要打开应用程序以获取更多信息。当我刚接触 iOS 时,我以为您实际上是通过推送通知发送图像/视频。您没有!
特别是在静默通知的情况下:
当设备收到后台通知时,系统可能会暂停 并延迟通知的传递,这可能会导致 以下副作用:
当系统收到新的后台通知时,它会丢弃旧的通知,只保留最新的通知。
如果有东西强制退出或杀死应用程序,系统会丢弃保留的通知。
如果用户启动应用程序,系统会立即发送暂停通知。 将后台更新推送到您的应用 docs
APN 每天发送有限数量的静默通知(带有内容可用密钥的通知)。此外,如果设备已经超过了当天的功率预算,则在功率预算重置之前不会再次发送静默通知,这种情况每天发生一次。从 Xcode 测试您的应用程序时,这些限制被禁用。请参阅将后台更新推送到您的应用。
Troubleshooting tips for handling errors returned from ANPs
即使对于远程用户通知,用户也可能无法上网,如果您发送的通知过多或过快,这可能会导致内容过期或 APN 会限制您。再来看看这里
长话短说,APN 和操作系统为王,而您则处于劣势。因此,您不能依赖它来遵守您的每个命令。话虽如此,从您看到大多数消息传递应用程序成功利用它的意义上来说,它是超级可靠的。
附录如何生成推送通知证书.p12
或.pem
以及如何测试?
看看这个terrific answer。它拥有我见过的最多的屏幕截图。
【讨论】:
“即使您禁用了应用后台刷新并禁用了允许通知,如果您的应用处于 FOREGROUND 中,您仍然可以收到静默通知。”我试过这个没有成功。您是否尝试过并看到它有效? @JohnL。我必须对其进行测试,稍后再与您联系。不知道什么时候,因为我需要设置东西来测试它 嗨,当我收到推送通知时,应用程序应该在后台激活并执行中给出的任务,(如用户的位置更新代码或其他代码),-(无效)应用程序:( UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler,但在用户点击通知之前,我的应用程序不会激活。当应用程序处于后台时,我将如何完成这项工作?我遵循了@Honey 所说但没有用的所有内容。剂量有人知道解决方案吗?我正在使用 FCM 进行通知。 @Moxarth 很难以这种方式帮助您。你能写一个新问题,然后向我们展示你所有的设置/有效负载/委托方法吗?也不要忘记 FCM 的键名不是content-available
我相信它是 content_available
。有关更多信息,请参阅here
这是我在 SO 上见过的最好的回应。谢谢@Honey【参考方案2】:
推送通知会让用户知道他们收到了通知(例如显示通知弹出窗口)。静默通知将更新,但用户不会收到有关它的通知。 在任何情况下,您都可以在无提示通知时执行操作,就像它是推送通知一样。唯一的区别是用户不会收到弹出通知的通知。
使用推送通知:
使用静默通知:
区别在于payload:
推送通知:
aps
content-available: 1
alert: ...
静默通知:
aps
content-available: 0
alert: ...
你必须在Capabilities中设置你选择的后台模式。
【讨论】:
推送通知?你的意思是推=远程。还是推送 = 远程 + 静音? 推送 = 远程 + 静音。唯一的区别是静默不会通过弹出窗口通知用户。无论如何,这只发生在应用程序处于后台时。如果应用程序在前台,用户永远不会收到弹出窗口的通知。 通知类型(远程、静默)是否在发送前在我的服务器上设置?或者它只是 iOS 用来根据手机状态对推送通知进行分类的一种方式? 为什么here 会说“包含这个值为 1 的键来配置静默通知”。是不是和图片所说的完全相反?! "content-available: 1" 表示静音。这实际上意味着,服务器上有可用的内容,去连接它以下载内容数据。因此,它会唤醒应用程序这样做,而不会让用户知道实际发生了什么。【参考方案3】:静默推送通知到达设备,用户对通知一无所知,但他的应用程序会收到通知,并且应用程序将有时间下载新内容并将其呈现给用户,无论应用程序的状态如何(即跑还是不跑)
只有在您的应用程序运行时才会调用远程推送通知方法。如果应用程序被挂起或未运行,则系统会在调用该方法之前唤醒或启动您的应用程序并将其置于后台运行状态。 此方法旨在向用户显示更新的内容。调用此方法时,您的应用程序有最多 30 秒的挂钟时间来执行下载操作并调用指定的完成处理程序块。如果没有及时调用处理程序,您的应用将被暂停。
有关更多技术细节,您可以通过以下链接:
Apple Notifications
Silent Notifications
【讨论】:
嗨,当我收到推送通知时,应用程序应该在后台激活并执行中给出的任务,(如用户的位置更新代码或其他代码),-(无效)应用程序:( UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler,但在用户点击通知之前,我的应用程序不会激活。当应用程序处于后台时,我将如何完成这项工作?。有人知道解决方案吗?我正在使用 FCM 进行通知。以上是关于iOS中都有哪些不同类型的通知以及如何正确配置它们?的主要内容,如果未能解决你的问题,请参考以下文章