[英]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.