检测是否通过推送通知打开了React Native iOS应用程序

检测应用程序是否从推送通知中启动/打开描述如何通过用户点击推送通知来检测本机iOS应用程序是否已打开(即启动或仅启用)。

我如何在React Native中做同样的事情? PushNotificationIOS让我附上通知侦听器…

 PushNotificationIOS.addEventListener('notification', function (notification) { console.log('got a notification', notification); }); 

但是当前台应用程序收到推送通知时, 以及当我通过推送通知打开应用程序时,会触发这两种情况。

我如何检测第二种情况?

这里有两种情况需要用不同的方式来检测:

  1. 该应用程序已被完全终止(例如,通过重新启动手机,或通过双击主屏幕并将其从背景中运行的应用程序列表中划掉),并由用户点击推送通知来启动。 这可以通过React.PushNotificationIOS.getInitialNotification方法检测到(以及获取通知的数据)。
  2. 该应用程序已被暂停,并通过用户点击推送通知而被重新激活。 就像在本地应用程序一样 ,您可以知道发生这种情况的原因是iOS在打开时(即使是旧通知)将窃听的通知传递给您的应用程序,并导致通知处理程序在应用程序处于UIApplicationStateInactive状态时触发或'background'状态,就像React Native的AppStateIOS类所调用的AppStateIOS )。

代码来处理这两种情况(你可以把它放在你的index.ios.js或其他地方在应用程序启动时运行):

 import React from 'react'; import { PushNotificationIOS, AppState } from 'react-native'; function appOpenedByNotificationTap(notification) { // This is your handler. The tapped notification gets passed in here. // Do whatever you like with it. console.log(notification); } PushNotificationIOS.getInitialNotification().then(function (notification) { if (notification != null) { appOpenedByNotificationTap(notification); } }); let backgroundNotification; PushNotificationIOS.addEventListener('notification', function (notification) { if (AppState.currentState === 'background') { backgroundNotification = notification; } }); AppState.addEventListener('change', function (new_state) { if (new_state === 'active' && backgroundNotification != null) { appOpenedByNotificationTap(backgroundNotification); backgroundNotification = null; } }); 

对于本地通知

getInitialNotification不适用于本地通知。

不幸的是,从React Native的0.28开始,使用PushNotificationIOS.getInitialNotification()总是在本地推送通知启动时返回一个null值。

因此,您需要在AppDelegate.m中将推送通知视为launchOption ,并将其作为appProperty传递给React Native。

以下是您需要从冷启动从后台/非活动状态接收本地推送通知的全部内容。

AppDelegate.m (原生iOS代码)

 // Inside of your didFinishLaunchingWithOptions method... // Create a Mutable Dictionary to hold the appProperties to pass to React Native. NSMutableDictionary *appProperties = [NSMutableDictionary dictionary]; if (launchOptions != nil) { // Get Local Notification used to launch application. UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; if (notification) { // Instead of passing the entire Notification, we'll pass the userInfo, // where a Record ID could be stored, for example. NSDictionary *notificationUserInfo = [notification userInfo]; [ appProperties setObject:notificationUserInfo forKey:@"initialNotificationUserInfo" ]; } } // Your RCTRootView stuff... rootView.appProperties = appProperties; 

index.ios.js (React Native)

 componentDidMount() { if (this.props.initialNotificationUserInfo) { console.log("Launched from Notification from Cold State"); // This is where you could get a Record ID from this.props.initialNotificationUserInfo // and redirect to the appropriate page, for example. } PushNotificationIOS.addEventListener('localNotification', this._onLocalNotification); } componentWillUnmount() { PushNotificationIOS.removeEventListener('localNotification', this._onLocalNotification); } _onLocalNotification( notification ) { if (AppState.currentState != 'active') { console.log("Launched from Notification from Background or Inactive state."); } else { console.log("Not Launched from Notification"); } } 

确保从react-native导入PushNotificationIOSAppState

我还没有使用远程推送通知进行testing。 也许@ MarkAmery的方法在远程推送通知中工作得很好,但不幸的是,就目前的React Native状态而言,这是我能够从冷态下获取本地推送通知的唯一方式。

这在React Native中是非常没有logging的,所以我在他们的GitHub仓库上创build了一个问题来引起注意,希望能够纠正它。 如果你正在处理这个问题,那么去那里,竖起大拇指,让它渗透到顶端。

https://github.com/facebook/react-native/issues/8580

我发现这个解决scheme有点怪异,依赖于我注意到的事件处理程序触发的一些潜在的奇怪行为。 我一直在努力的应用程序需要相同的function,特别是当我通过推送通知打开应用程序检测。

我发现PushNotificationIOS的处理程序在AppStateIOS处理程序之前AppStateIOS 。这意味着如果我将前台/后台状态保存到内存/ AsyncStorage中,我可以在PushNotification事件处理程序中像这样检查它: if (activity === 'background') ,如果这是真的,那么我知道我刚从推送通知打开了应用程序。

我总是保持AppStateIOS前台/后台活动在内存和磁盘上(分别使用redux和redux-persist),所以我只需要检查一下每当我需要知道的时候。

这可能对您的目的来说太过于冒险,而且这种行为在未来可能会改变,或者可能只是本地化。 试着看看这个解决scheme,看看你的想法。