问题描述
首先,只是为了澄清...
在提出这个重复问题"之前,我已经对现有资源(媒体、stackoverflow、苹果开发者论坛等)进行了相当多的搜索和阅读.确认和总结我的知识是正确的.
I have done quite some searchings and readings on the existing sources (medium, stackoverflow, apple developer forum, etc.) before asking this "duplicate question" for confirming and concluding my knowledge is correct.
- 如果我的应用被用户强制退出,iOS 会在后台启动我的应用吗?
- 如何在不点击横幅/警报的情况下强制退出/向上滑动以杀死 iOS 应用程序时获取推送通知负载?
- https://medium.com/fenrir-inc/handling-ios-push-notifications-the-not-so-apparent-side-420891ddf10b
- 在应用终止时处理推送通知
- https://developer.apple.com/forums/thread/62005#:~:text=In%20most%20cases%2C%20the%20system,force%20quit%20by%20the%20 个用户.
在我们开始之前,只是用非常精确的方式来表达这些术语.当我提到时,这就是我所指的
Before we begin, just to put the terms in very precise manner. Here's what I'm referring when I mention
- 前台 - 应用处于活动状态且正在运行,用户基本上与应用进行交互
- 背景 - 用户在交互后点击主页按钮.应用保持在后台,用户可以双击主页按钮并从应用切换器中找到该应用.
- 退出 - 应用实际上在后台,但被系统本身终止.
- Kill - 应用不再处于后台,用户双击主页按钮并将应用从应用切换器中滑开.
我正在尝试解决的用例
应用程序在背景、退出& 中接收推送通知KILL 状态然后执行某些后台操作(更新应用程序徽章 + 在设备中存储通知)
App receive push notification in BACKGROUND, QUIT & KILL states then perform certain background actions (updating Application Badge + storing the Notification in device)
- 对于背景 - 是的,我已经通过在 APNS 负载中将
content-available = 1
一起发送来实现这一点.出现通知横幅,执行后台操作! - 对于 QUIT - 是的,我已经通过将
content-available = 1
在 APNS 负载中一起发送来实现这一点.出现通知横幅,执行后台操作! - 对于 KILL - 出现通知横幅,但不会触发后台操作.
- For background - Yes I've managed to achieve this by having
content-available = 1
sent together in APNS payload. Notification banner appear, background action executed! - For QUIT - Yes I've managed to achieve this by having
content-available = 1
sent together in APNS payload. Notification banner appear, background action executed! - For KILL - Notification banner appear, BUT background action is not trigger.
我的问题
- 每当应用被终止时,是否无法在收到通知时唤醒应用以执行任何后台操作?
- 它如何适用于 Whatsapp 等消息传递应用程序?
- 当应用被强制退出时,我应该如何处理我的情况?
只有当用户点击通知横幅时,我的应用才能运行这些后台操作(增加徽章计数 + 存储数据).
ONLY if user tapped notification banner, my app gets to run those background actions (Increase badge count + storing the data).
否则,如果用户选择点击应用程序图标来打开我的应用程序.推送的通知在我的应用中根本不存在,包括徽章数量没有增加.
Otherwise, if user choose to tap on App Icon to open my app. The pushed notification won't exist in my app at all, including badge count is not increase.
背景状态
- 打开 Whatsapp,点按主页按钮(将应用保持在后台)
- 在设备中发送短信,出现横幅通知
- 点按应用程序图标打开应用程序,应用程序中有消息.
强制退出状态
- 打开 Whatsapp,双击主页按钮,滑动应用程序
- 在设备中发送短信,出现横幅通知.
- 点按应用程序图标打开应用程序,应用程序中有消息.
强制退出状态 + WiFi &蜂窝数据已关闭
- 打开 Whatsapp,双击主页按钮,滑动应用程序
- 在设备中发送短信,出现横幅通知
- 关闭 WiFi 和蜂窝数据已关闭.(确认并尝试通过 Safari 访问网站)
- 点按应用程序图标打开应用程序,应用程序中有消息.
使用 Whatsapp 的测试基本上得出结论,可以让您的应用唤醒以执行后台操作(特别是在 FORCE QUIT State + WiFi & Cellular 数据关闭的情况下)
The tests with Whatsapp, basically concludes that it's possible to have your app awake to perform background actions (Especially with the case of FORCE QUIT State + WiFi & Cellular data turned OFF)
唯一的解释"我可以解释自己是,他们使用 PushKit 通知框架而不是用户通知框架.
The only "explanation" I'm able to explain myself is, they are using PushKit notifications Framework instead of User Notification Framework.
显然在 iOS 13 上,就像@hubsi 在评论中提到的以及来自 苹果论坛.即使应用被用户手动终止,iOS 13 也会唤醒我的应用.
Apparently on iOS 13, like what @hubsi has mentioned down at the comment as well as some comments from Apple forum. iOS 13 does wakes my app even the app was manually killed by the user.
推荐答案
更新 swift 5.x Plus iOS 14.x
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { DispatchQueue.main.asyncAfter(deadline: .now() + 2) { self.deplinkNotification(userInfo: response.notification.request.content.userInfo ) } }
更新:除了下面提到的内容之外,似乎从 iOS 13 开始,当收到处于终止状态的推送通知时,应用程序实际上会启动.我发现为了让
didReceiveRemoteNotification:fetchCompletionHandler
委托触发,应用程序需要在启动时尽快启动registerForRemoteNotifications (UIApplication)
方法(例如在 didFinishLaunchingWithOptions 中).在 React Native 的情况下,与下面所述相反,您实际上可以运行 JS 代码.尽管您必须等待 RN 在运行代码之前启动,例如像这样:Update: In addition to what's mentioned below, it seems that as of iOS 13 apps get actually launched when a push notification is received in killed state.I found that in order to have the
didReceiveRemoteNotification:fetchCompletionHandler
delegate to trigger, the app needs to launch theregisterForRemoteNotifications (UIApplication)
method asap when launched (e.g. in didFinishLaunchingWithOptions).In case of React Native, opposed to what's stated below, you can actually run JS code. Though you have to wait for RN to have launched before running code, e.g. like this:public class func didReceiveRemoteNotification(_ userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { DispatchQueue.main.asyncAfter(deadline: .now() + 5) { // some RN bridged method/event } }
旧答案:
当在 iOS 上收到推送通知且应用被终止时,有两种方法可以让代码运行:
There are two ways to have code run when a push notifications is received on iOS with the app being killed:
- 通过使用 PushKit 框架
注意:Apple 仅允许将 PushKit 框架用于 VoIP 和 watchOS 应用程序,因此在没有实际要求的情况下使用它您的应用程序可能无法通过 Apple 的审核 - 通过使用通知服务扩展
使用这个扩展可以让你在后台运行(无头)代码,包括丰富"代码.通知,例如带有图片附件
至于 WhatsApp,我很确定他们正在使用 PushKit(他们无论如何都需要它来接听电话).虽然我认为您在上次测试中描述的内容也可以使用通知服务扩展:
在扩展程序中,您可以处理推送通知,包括其有效负载并将数据(例如聊天消息)写入本地应用程序存储(例如通过应用程序组与您的主应用程序共享).当应用程序打开时,它会从存储中读取该数据(在没有数据网络的情况下显示聊天消息).As for WhatsApp I'm pretty sure they're using PushKit (they require it anyway for incoming calls). Though I think what you described in your last test would also be possible using a Notification Service Extension:
In the extension you can process the pushed notification including its payload and write data (e.g. the chat message) to your local app storage (e.g. shared with your main app through App Groups). When the app gets opened it reads that data from storage (chat message appears without data network).由于问题被标记为react-native":请注意,据我所知,不可能在通知服务扩展中调用 RN 桥接 JavaScript 代码.您必须编写本机 (Swift/Obj-C) 代码.
Since the question is tagged with "react-native": Please note that to my knowledge it's not possible to invoke RN bridged JavaScript code in a Notification Service Extension. You'd have to write native (Swift/Obj-C) code.
这篇关于用户强制退出应用程序时如何处理推送通知?[iOS]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!