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

React Native iOS端OneSignal后台通知TestFlight部署异常问题

React Native + OneSignal 后台通知TestFlight构建问题

我按照OneSignal官方指南配置了React Native应用的后台通知。通过Xcode直接安装到设备时,后台通知正常工作;但归档构建后从TestFlight安装时,虽然能收到推送通知,但我添加的emitNotificationEvent事件完全没触发。用Xcode设备控制台排查发现,TestFlight构建里NotificationExtensionModule.m的_instance是空的。

备注

  • Xcode版本:13.4
  • 两种安装方式都能正常接收推送通知
  • 上传TestFlight只增加了构建版本号,应用版本号保持不变
  • 已尝试清理构建文件夹、重新安装Pods,问题依旧

以下是相关代码片段:

AppDelegate.h

#import <Foundation/Foundation.h>
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>


@interface AppDelegate : UIResponder <UIApplicationDelegate,RCTBridgeDelegate,UNUserNotificationCenterDelegate>

@property (nonatomic, strong) UIWindow *window;

@end

AppDelegate.m

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
  //access NotificationServiceExtensionModule emitNotificationEvent method
  [NotificationServiceExtensionModule.sharedInstance emitNotificationEvent:userInfo ];
  completionHandler(UIBackgroundFetchResultNoData);
}

NotificationServiceExtensionModule.h

#import <foundation/Foundation.h>

// NotificationServiceExtensionModule.h
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface NotificationServiceExtensionModule : RCTEventEmitter <RCTBridgeModule>

+ (NotificationServiceExtensionModule*) sharedInstance;
- (void)emitNotificationEvent:(NSDictionary *)userInfo;


@end

NotificationServiceExtensionModule.m

#import <Foundation/Foundation.h>

// NotificationServiceExtensionModule.m
#import "NotificationServiceExtensionModule.h"

@implementation NotificationServiceExtensionModule

static NotificationServiceExtensionModule* _instance = nil;


+(NotificationServiceExtensionModule*) sharedInstance {
//    @synchronized( _instance ) {
//        if( !_instance ) {
//            _instance = [[NotificationServiceExtensionModule alloc] init];
//        }
//    }
    
    return _instance; // this returns null when installed from TestFlight. 
}

// To export a module named NotificationServiceExtensionModule
RCT_EXPORT_MODULE();

- (NSArray<NSString *> *)supportedEvents
{
  NSLog(@"Supported EVENTS__________________________");
  _instance = self;
  return @[@"NotificationEvent"];
}

- (void)emitNotificationEvent:(NSDictionary *)userInfo
{
  NSString *eventName = userInfo[@"custom"][@"a"];
  [self sendEventWithName:@"NotificationEvent" body:@{
"notificationPayload": eventName}];
}

@end

问题原因及解决方案

核心原因

TestFlight构建开启了App Thinning/bitcode,或Release模式下的编译优化导致React Native模块初始化时机延迟,supportedEvents方法还未被调用时,AppDelegate就已经调用了sharedInstance,此时_instance还未赋值,返回空指针。另外你的单例实现没有主动初始化逻辑,完全依赖supportedEvents的赋值,进一步放大了这个问题。

具体修复方案

  1. 修复单例初始化逻辑
    改成线程安全的懒加载初始化,确保第一次调用sharedInstance时就能创建实例,不再依赖supportedEvents:

    +(NotificationServiceExtensionModule*) sharedInstance {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _instance = [[NotificationServiceExtensionModule alloc] init];
        });
        return _instance;
    }
    
  2. 延迟调用事件发送
    在AppDelegate中给React Native桥接留足初始化时间,避免提前调用空实例:

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
    {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NotificationServiceExtensionModule *module = [NotificationServiceExtensionModule sharedInstance];
            if (module != nil) {
                [module emitNotificationEvent:userInfo];
            }
        });
        completionHandler(UIBackgroundFetchResultNoData);
    }
    
  3. 调整Release模式编译优化
    进入Xcode的Target设置,找到Build Settings -> Optimization Level,将Release模式下的优化暂时改为None [-O0]测试。如果问题解决,再逐步调整到合适的优化等级,避免编译器误优化_instance的赋值逻辑。

  4. 验证Extension配置
    确保Notification Service Extension的Bundle ID是主App Bundle ID的合法后缀(比如.notification-service),且在TestFlight构建中未被App Thinning忽略。可以在归档分发时,确认Extension被包含在构建包内。

内容的提问来源于stack exchange,提问作者Shamique

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:05:21