You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:10:36