当应用程序未激活(已终止)时,推送通知无法正常工作

Posted

技术标签:

【中文标题】当应用程序未激活(已终止)时,推送通知无法正常工作【英文标题】:Push notifications not working properly when the app is not active (killed) 【发布时间】:2016-10-24 00:49:24 【问题描述】:

我在推送通知方面遇到问题,我正在使用 Google Cloud Messaging,

我的问题是我的应用程序使用一些缓存数据,我使用来自推送通知的数据刷新该缓存,因此当应用程序被用户杀死(主页按钮 + 向上滑动)并且应用程序收到推送通知它不调用方法didReceiveRemoteNotification,因此应用程序无法访问该通知的有效负载并更新缓存的数据。

那么,有没有办法做到这一点?

只有当用户点击通知并且应用程序通过application:didFinishLaunchingWithOptions 方法获取它时?

如果用户通过单击应用程序图标打开应用程序,我无法获取通知的有效负载?

PD:如果应用程序在前台或后台(未终止),它可以完美运行

【问题讨论】:

【参考方案1】:

如果您希望您的应用即使在被终止时也能收到推送通知,请将密钥 "content-available":"1" 添加到推送有效负载中。

看here

编辑: 在挖掘了更多之后,我发现静默推送(例如content-available:1),如果它被用户杀死,它不会唤醒应用程序:

但是,如果用户强制退出,系统不会自动启动您的应用

我必须说,我真的不明白为什么当静默推送到达时操作系统不让我的应用在它死了时唤醒。那还有什么意义???

【讨论】:

是的,我正在使用它并且当应用程序处于前台或后台时工作,但当应用程序被用户杀死时则不工作 @RobertoFrontado,显然做不到……看看我的补充。 这似乎是不可能的:S 无论如何谢谢【参考方案2】:

这是预期的行为。 didReceiveRemoteNotification 不会在用户终止应用时被调用,除非您的应用具有 VoIP 权限。

【讨论】:

你是什么意思?如果我启用 VoIP 权限,它会按我的意愿工作吗? 应该的。但是您的应用程序是 VoIP 应用程序(如 WhatsApp)吗?如果不是,它将被 App Store 拒绝。 不,它不使用 VoIP,所以我猜他们会拒绝我的应用哈哈哈谢谢【参考方案3】:

如果应用程序被终止。 application:didFinishLaunchingWithOptionsapplication:didReceiveRemoteNotification:fetchCompletionHandler:都被调用。在前一个。远程或本地通知的键在选项参数中传递。只有在远程通知时才调用后一个。该过程在 Apple Docs Here. 中有详细说明。快照也粘贴在这里。

处理可操作的通知

如果您的应用没有在前台运行,为了处理用户只是滑动或点击通知时的默认操作,ios 在前台启动您的应用并调用UIApplicationDelegate 方法application:didFinishLaunchingWithOptions: 传入本地选项字典中的通知或远程通知。在远程通知的情况下,系统也会调用application:didReceiveRemoteNotification:fetchCompletionHandler:

如果您的应用已经在前台,iOS 不会显示通知。相反,为了处理默认操作,它调用UIApplicationDelegate 方法之一application:didReceiveLocalNotification:application:didReceiveRemoteNotification:fetchCompletionHandler:。 (如果不实现application:didReceiveRemoteNotification:fetchCompletionHandler:,iOS会调用application:didReceiveRemoteNotification:。)

最后,要处理 iOS 8 或更新版本中可用的自定义操作,您需要在您的应用委托上至少实现两个新方法之一,application:handleActionWithIdentifier:forRemoteNotification:completionHandler:application:handleActionWithIdentifier:forLocalNotification:completionHandler:。在任何一种情况下,您都会收到操作标识符,您可以使用它来确定点击了什么操作。您还会收到远程或本地通知,您可以使用它来检索处理该操作所需的任何信息。最后,系统将完成处理程序传递给您,您必须在完成操作处理后调用它。清单 2-8 显示了一个调用自定义操作处理程序方法的示例实现。参考Apple Docs

编辑:

用户点击警报中的默认按钮或点击(或点击)应用程序图标。如果点击默认操作按钮(在运行 iOS 的设备上),系统将启动应用程序并应用程序调用其委托的 application:didFinishLaunchingWithOptions: 方法,传入通知负载(用于远程通知)或本地通知对象(用于本地通知)。尽管 application:didFinishLaunchingWithOptions: 不是处理通知的最佳位置,但此时获取有效负载使您有机会在调用处理程序方法之前启动更新过程。 参考:Apple Docs

【讨论】:

感谢您的回答,但如果用户通过单击应用程序图标打开应用程序,我将无法访问通知负载,对吗? 但是当我收到通过点击应用图标打开应用的通知时,application:didFinishLaunchingWithOptions: 方法中的launchingOptions 始终是nil 在通知徽章出现时尝试录音。如果有什么事情请告诉我 得到了相同的结果,但是如果我点击通知,它会起作用,虽然我不能强迫用户这样做,如果他们想通过图标打开应用程序,我无能为力吗? 是的,点击通知确实有效,但文档说明了这一点。让我想想别的办法【参考方案4】:

当应用程序被终止并且触发的推送通知包含一些可操作的按钮时。当我们点击 Push Notification 的 Action Button 时:

第一个被执行的委托是:

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

但这里的launchOptionsnil

执行的第二个委托是:

-(void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(nonnull NSDictionary *)userInfo completionHandler:(nonnull void (^)())completionHandler

在此变量userInfo 包含推送通知的所有有效负载。在identifier 的帮助下,我们可以确定调用了哪个操作,然后执行我们各自的操作。

【讨论】:

【参考方案5】:

在您的项目中添加通知服务扩展的目标,它包含两种方法

【讨论】:

以上是关于当应用程序未激活(已终止)时,推送通知无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

当应用程序处于后台状态时,FCM 多个推送通知无法正常工作

推送通知无法正常工作,当应用程序在后台时,Swift

当应用程序处于后台状态时,FCM多次推送通知无法正常工作

如果应用程序终止,则未收到 iOS FCM 推送通知

应用程序被终止时未收到推送通知 - iOS

Android - 包含 click_action 后未收到 FCM 推送通知