检测是否通过推送通知

时间:2015-12-17 14:34:22

标签: ios react-native

Detect if the app was launched/opened from a push notification描述了如何通过用户点按推送通知来检测本机iOS应用是否已打开(即启动或仅启动)。

如何在React Native中执行相同的操作? PushNotificationIOS让我附上通知听众......

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

但是,当我通过推送通知打开应用程序时,当前台的应用程序收到推送通知,时,这会触发。

我如何特别检测第二种情况?

3 个答案:

答案 0 :(得分:36)

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

  1. 该应用已完全终止(例如,通过重新启动手机,或双击主页并将其从背景中运行的应用列表中轻扫)并由用户启动&# 39;点击推送通知。这可以通过React.PushNotificationIOS.getInitialNotification方法检测到(以及获取通知的数据)。
  2. 该应用已被暂停,并且用户点击推送通知后再次激活该应用。只需like in a native app,您就可以知道这种情况正在发生,因为iOS会在您的应用打开时将点击通知传递给您的应用(即使它是一个旧通知)并导致您的通知处理程序在您的应用启动时触发在UIApplicationStateInactive州(或'background'州,正如React Native的AppStateIOS类所称的那样)。
  3. 处理这两种情况的代码(您可以将其放在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;
      }
    });
    

答案 1 :(得分:8)

对于本地通知

getInitialNotification不适用于本地通知。

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

因此,您需要在launchOption中将推送通知作为AppDelegate.m抓取,并将其作为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");
  }
}

确保从PushNotificationIOS导入AppStatereact-native

我没有使用远程推送通知对此进行测试。也许@MarkAmery的方法适用于远程推送通知但不幸的是,从React Native的当前状态来看,这是我能够从冷状态工作中获得本地推送通知的唯一方法。

这在React Native中是高度无证的,所以我在他们的GitHub回购中创建了an issue以引起对它的注意,并希望能够纠正它。如果您正在处理此问题,请转到此处并竖起大拇指,使其渗透到顶部。

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

答案 2 :(得分:0)

我找到的解决方案有点hacky并且依赖于我注意到的关于事件处理程序触发的顺序的一些可能奇怪的行为。我一直在使用的应用程序需要相同的功能,以便在我通过推送通知打开应用程序时进行检测。

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

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

对于您的目的而言,这可能过于苛刻,并且该行为可能在将来发生变化,或者可能仅仅局限于我。尝试查看该解决方案,看看你的想法。