[英]Detect whether React Native iOS app was opened via push notification
检测应用程序是否通过推送通知启动/打开,描述了如何通过用户点击推送通知来检测本机iOS应用程序是否已打开(即启动或仅启动)。
我如何在React Native中做同样的事情? PushNotificationIOS
允许我附加通知监听器...
PushNotificationIOS.addEventListener('notification', function (notification) {
console.log('got a notification', notification);
});
但是当在前台接收到应用程序的推送通知时, 以及当我通过推送通知打开应用程序时,这都会触发。
如何特别检测第二种情况?
这里有两种情况需要以不同的方式检测:
React.PushNotificationIOS.getInitialNotification
方法检测(并获取通知的数据)。 UIApplicationStateInactive
状态时触发通知处理程序(或'background'
状态,如React Native的AppStateIOS
类所调用的AppStateIOS
)。 用于处理这两种情况的代码(您可以将它放在index.ios.js
或其他在app启动时运行的地方):
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
值。
正因为如此,你需要捕捉推送通知的launchOption
在AppDelegate.m
并把它传递到本地做出反应作为appProperty
。
以下是从冷启动或后台/非活动状态接收本地推送通知所需的全部内容。
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
导入PushNotificationIOS
和AppState
。
我还没有使用远程推送通知进行测试。 也许@MarkAmery的方法可以很好地使用远程推送通知但不幸的是,从React Native的当前状态来看,这是我能够从冷状态工作获得本地推送通知的唯一方法。
这在React Native中是高度无证的,所以我在他们的GitHub repo上创建了一个问题 ,以引起对它的注意,并希望纠正它。 如果您正在处理此问题,请转到此处并竖起大拇指,使其渗透到顶部。
我找到的解决方案有点hacky并且依赖于我注意到的关于事件处理程序触发的顺序的一些可能奇怪的行为。 我一直在努力的应用程序需要相同的功能,以便在我通过推送通知打开应用程序时进行具体检测。
我发现,该处理程序PushNotificationIOS
的处理程序之前,火灾AppStateIOS
这是什么意思是,如果我坚持前台/后台状态记忆/ AsyncStorage,我可以检查它像这样在PushNotification事件处理程序: if (activity === 'background')
如果那是真的那么我知道我刚从推送通知中打开了应用程序。
我总是在内存和磁盘上保存AppStateIOS
前台/后台活动(分别使用redux和redux-persist),所以我只需要在需要知道的时候检查。
对于您的目的而言,这可能过于苛刻,并且该行为可能在将来发生变化,或者可能仅仅局限于我。 尝试查看该解决方案,看看你的想法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.