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

React Native iOS仅Release构建时pushViewController报错

React Native iOS Release构建导航控制器类型不匹配问题

Debug构建正常,但切换到Release构建或使用eas build生成IPA时,调用原生模块openPendingAuthorization方法会抛出unrecognized selector sent to instance-pushviewcontrolleranimated错误——此时获取到的根视图控制器是普通ViewController而非预期的UINavigationController,Debug模式无此异常。

相关代码

AppDelegate.mm

UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:nil];               
rootView.backgroundColor = [UIColor whiteColor];                                                                                 

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];                                                     
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];                                                 

UIViewController *reactViewController = [storyboard instantiateViewControllerWithIdentifier: @"ReactViewController"];           
reactViewController.view = rootView;                                                                                             

UINavigationController *navController = (UINavigationController*)[storyboard 
                    instantiateViewControllerWithIdentifier: @"UINavigationController"];       
[navController pushViewController:viewController animated:YES];
self.navController = navController;                                                                                              
self.window.rootViewController = navController;                                                                                  

[self.window makeKeyAndVisible];                                                                                                  
[super application:application didFinishLaunchingWithOptions:launchOptions];
return YES;

Homescreen.tsx

SdkModule.openPendingAuthorization(                                                                                        
  RAS_USER_ID,                                                                                                                  
  RAS_CLIENT_ID,                                                                                                                
  RAS_CLIENT_SECRET,                                                                                                            
  RAS_URL                                                                                                                       
)                                                                                                                               

RCTSdkModule.m

RCT_EXPORT_METHOD(openPendingAuthorization:(NSString *)userId
                                  clientId:(NSString *)clientId
                                  clientSecret:(NSString *)clientSecret
                                  url:(NSString *)url)
{  
    Data *obj=[Data getInstance];
    obj.userId = userId;
    obj.clientId = clientId;
    obj.clientSecret = clientSecret;
    obj.url = url;
  
    dispatch_async(dispatch_get_main_queue(), ^{
      UIApplication *app = [UIApplication sharedApplication];
      UINavigationController *nav = (UINavigationController *) app.delegate.window.rootViewController;
      UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
      UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier: @"SdkViewController"];
      [nav pushViewController:viewController animated:YES];
    });
}

SdkViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    // SDK Related Code
}

解决方案

1. 增加类型校验,避免强制转换风险

在原生模块中获取根视图控制器时,先校验类型再执行操作,防止类型不匹配导致崩溃:

dispatch_async(dispatch_get_main_queue(), ^{
  UIApplication *app = [UIApplication sharedApplication];
  UIViewController *rootVC = app.delegate.window.rootViewController;
  
  UINavigationController *nav = nil;
  // 直接判断根VC是否为导航控制器
  if ([rootVC isKindOfClass:[UINavigationController class]]) {
      nav = (UINavigationController *)rootVC;
  } 
  // 检查是否是被present的导航控制器
  else if (rootVC.presentedViewController && [rootVC.presentedViewController isKindOfClass:[UINavigationController class]]) {
      nav = (UINavigationController *)rootVC.presentedViewController;
  } 
  // 若没有导航控制器,临时包裹一层
  else {
      nav = [[UINavigationController alloc] initWithRootViewController:rootVC];
      app.delegate.window.rootViewController = nav;
      [app.delegate.window makeKeyAndVisible];
  }
  
  UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
  UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier: @"SdkViewController"];
  [nav pushViewController:viewController animated:YES];
});

2. 优化导航控制器初始化方式

避免依赖故事板实例化导航控制器,直接代码创建可规避Release模式下的故事板加载异常:

// 替换AppDelegate中故事板实例化导航控制器的代码
// 注意:原代码中`viewController`未定义,需先实例化或替换为目标VC
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:reactViewController];
// 若需提前推入其他VC,确保viewController已正确实例化
// [navController pushViewController:viewController animated:YES];
self.navController = navController;
self.window.rootViewController = navController;

3. 检查Release构建配置

  • 确认Dead Code Stripping选项在Release模式下未误移除导航控制器相关代码
  • 验证Main.storyboard已被正确添加到Release构建的资源包中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:30:46