iOS中通过通知操作启动React Native应用时getInitialNotification返回null
解决iOS长按通知操作启动React Native应用时getInitialNotification返回null的问题
问题根源
长按通知的操作按钮属于iOS的通知响应操作,getInitialNotification仅能捕获普通点击通知启动应用的场景,无法识别这种通过操作按钮启动的情况,因此返回null。
解决方案
需要通过原生iOS端捕获通知操作事件,并将通知数据传递给React Native端,补充getInitialNotification的逻辑。
步骤1:iOS原生端捕获通知操作
在AppDelegate中实现userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:方法,将通知数据存入UserDefaults:
Swift 示例
import UserNotifications func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { // 提取通知的自定义数据 let notificationPayload = response.notification.request.content.userInfo // 存入UserDefaults,供RN读取 UserDefaults.standard.set(notificationPayload, forKey: "InitialNotificationAction") UserDefaults.standard.synchronize() completionHandler() }
Objective-C 示例
#import <UserNotifications/UserNotifications.h> - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler { NSDictionary *notificationPayload = response.notification.request.content.userInfo; [[NSUserDefaults standardUserDefaults] setObject:notificationPayload forKey:@"InitialNotificationAction"]; [[NSUserDefaults standardUserDefaults] synchronize]; completionHandler(); }
步骤2:React Native端读取补充数据
封装一个新的方法,先尝试调用getInitialNotification,如果返回null,则读取UserDefaults中的存储数据,处理后清空存储避免重复触发:
首先需要实现一个简单的UserDefaults原生模块(或使用第三方库如react-native-shared-preferences),以下是自定义模块的核心代码:
iOS原生模块(Swift)
import Foundation import React @objc(UserDefaultsModule) class UserDefaultsModule: NSObject, RCTBridgeModule { static func moduleName() -> String! { return "UserDefaults" } static func requiresMainQueueSetup() -> Bool { return true } @objc func get(_ key: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { let value = UserDefaults.standard.object(forKey: key) resolve(value) } @objc func remove(_ key: String) { UserDefaults.standard.removeObject(forKey: key) UserDefaults.standard.synchronize() } }
React Native端调用代码
import { Platform, NativeModules } from 'react-native'; import PushNotificationIOS from '@react-native-community/push-notification-ios'; const { UserDefaults } = NativeModules; // 封装获取初始通知(含操作按钮场景)的方法 const getInitialNotificationWithActionSupport = async () => { // 先尝试原方法 const initialNotification = await PushNotificationIOS.getInitialNotification(); if (initialNotification) { return initialNotification; } // iOS下检查操作按钮触发的通知数据 if (Platform.OS === 'ios') { try { const actionNotification = await UserDefaults.get('InitialNotificationAction'); if (actionNotification) { // 清空存储,防止下次冷启动重复处理 UserDefaults.remove('InitialNotificationAction'); // 转换为和getInitialNotification一致的返回格式 return { data: actionNotification, // 可根据需求补充其他字段(如alert、sound等) }; } } catch (error) { console.error('读取通知操作数据失败:', error); } } return null; }; // 使用示例 getInitialNotificationWithActionSupport().then(notification => { if (notification) { // 处理应用由通知(含操作按钮)启动的逻辑 console.log('应用由通知启动:', notification.data); // 比如跳转对应页面、处理业务逻辑等 } else { // 应用正常启动的逻辑 } });
注意事项
- 处理完通知数据后必须清空
UserDefaults中的存储,避免后续冷启动重复触发逻辑。 - 确保iOS端已正确配置通知权限和UNUserNotificationCenter代理。
- 如果使用第三方存储库,需对应调整RN端的读取/删除逻辑。
内容的提问来源于stack exchange,提问作者Varun Gupta
相关产品推荐
相关产品推荐

