Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App Crashes with message "-[RCTView setSheetLargestUndimmedDetent:]: unrecognized selector sent to instance" #2166

Open
hoonjoo-park opened this issue May 30, 2024 · 3 comments
Labels
Missing info The user didn't precise the problem enough Missing repro This issue need minimum repro scenario Platform: iOS This issue is specific to iOS

Comments

@hoonjoo-park
Copy link

hoonjoo-park commented May 30, 2024

Description

Problem

First of all, I've integrated ReactNative with my iOS native App.
There is no problem with using the basic components of ReactNative. However, when I register RootStackNavigator as an entryPoint, the app crashes with the following error:

-[RCTView setSheetLargestUndimmedDetent:]: unrecognized selector sent to instance

As I said above, my app is based on iOS, and only a few screens are implemented with ReactNative.
so I had to implement my custom BridgeManager which returns rootViewFactory to render ReactNative View.


React Native Code Example:

index.js

const { AppRegistry } = require('react-native')
import 'react-native-gesture-handler'
import 'react-native-reanimated'
import NoticeRootStackNavigator from './src/navigation/notice/NoticeRootStackNavigator'

AppRegistry.registerComponent('NoticeList', () => NoticeRootStackNavigator)

NoticeRootStackNavigator

export type NoticeStackParamList = {
  NoticeList: undefined;
  NoticeDetail: undefined;
}

export type NoticeNavigationProp = StackNavigationProp<NoticeStackParamList>;

const NoticeStack = createStackNavigator<NoticeStackParamList>();

const NoticeRootStackNavigator = () => {
  const screenOptions = useNavigatorScreenOptions();

  return (
    <NavigationContainer>
      <NoticeStack.Navigator screenOptions={screenOptions} initialRouteName="NoticeList">
        <NoticeStack.Screen name="NoticeList" component={NoticeList} />
        <NoticeStack.Screen name="NoticeDetail" component={NoticeDetail} />
      </NoticeStack.Navigator>
    </NavigationContainer>
  );
}

export default memo(NoticeRootStackNavigator);

iOS Code Example

CustomRCTBridgeManager.mm

#import "CustomRCTBridgeManager.h"
#import "RCTAppSetupUtils.h"
#import <React/RCTComponentViewFactory.h>
#import <React/CoreModulesPlugins.h>

@interface CustomRCTBridgeManager () <RCTTurboModuleManagerDelegate>
@end


@implementation CustomRCTBridgeManager

+ (instancetype)shared {
    static CustomRCTBridgeManager *shared = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [[self alloc] init];
    });
    return shared;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        [self configureBridge];
    }
    return self;
}

- (void)configureBridge {
    _rootViewFactory = [self createRCTRootViewFactory];
    _bridge = _rootViewFactory.bridge;
}

- (UIView *)createRootView: (NSString *)moduleName andInitialProperties:(NSDictionary * _Nullable)initialProperties {
    if (initialProperties == nil) {
        initialProperties = self.initialProps;
    }
    
    return [self.rootViewFactory viewWithModuleName:moduleName
                                  initialProperties:initialProperties
                                      launchOptions:nil];
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
#if DEBUG
    return [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];
#else
    return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];

#endif
}

#pragma mark - New Arch Enabled settings

- (BOOL)newArchEnabled
{
#if RCT_NEW_ARCH_ENABLED
    return YES;
#else
    return NO;
#endif
}

- (BOOL)turboModuleEnabled
{
    return [self newArchEnabled];
}

- (BOOL)fabricEnabled
{
    return [self newArchEnabled];
}

- (BOOL)bridgelessEnabled
{
    return [self newArchEnabled];
}

#pragma mark - RCTTurboModuleManagerDelegate

- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
    return RCTAppSetupDefaultModuleFromClass(moduleClass);
}

- (Class)getModuleClassFromName:(const char *)name {
#if RN_DISABLE_OSS_PLUGIN_HEADER
    return RCTTurboModulePluginClassProvider(name);
#else
    return RCTCoreModulesClassProvider(name);
#endif
}

- (RCTRootViewFactory *)createRCTRootViewFactory
{
    __weak __typeof(self) weakSelf = self;
    RCTBundleURLBlock bundleUrlBlock = ^{
        return [weakSelf sourceURLForBridge:weakSelf.bridge];
    };
    
    RCTRootViewFactoryConfiguration *configuration =
    [[RCTRootViewFactoryConfiguration alloc] initWithBundleURLBlock:bundleUrlBlock
                                                     newArchEnabled:self.fabricEnabled
                                                 turboModuleEnabled:self.turboModuleEnabled
                                                  bridgelessEnabled:self.bridgelessEnabled];
    
    return [[RCTRootViewFactory alloc] initWithConfiguration:configuration andTurboModuleManagerDelegate:self];
}

@end

NoticeViewController

final class NoticeListViewController: ReactNativeViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.navigationItem.title = "NoticeList"
        
        configureRCTView()
    }
    
    
    private func configureRCTView() {
        guard let bridgeManager = QandaRCTBridgeManager.shared() else { return }
        
        let reactView = bridgeManager.createRootView(ReactNativeScreen.notice, andInitialProperties: nil)
        
        self.view = reactView
    }
}

Steps to reproduce

  1. enable new architecture by running RCT_NEW_ARCH_ENABLED=1 bundle exec pod install
  2. navigate to ViewController which it's view is RNScreen
  3. it successfully loads bundle from metro server
  4. after loading finished, app crashes.

Snack or a link to a repository

sorry it's my company's private repo

Screens version

3.31.1

React Native version

0.74.2

Platforms

iOS

JavaScript runtime

Hermes

Workflow

React Native (without Expo)

Architecture

Fabric (New Architecture)

Build type

Debug mode

Device

iOS simulator

Device model

iPhone 15 Pro

Acknowledgements

Yes

@github-actions github-actions bot added Platform: iOS This issue is specific to iOS Missing repro This issue need minimum repro scenario labels May 30, 2024
Copy link

Hey! 👋

The issue doesn't seem to contain a minimal reproduction.

Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?

Copy link

github-actions bot commented May 30, 2024

Hey! 👋

It looks like you've omitted a few important sections from the issue template.

Please complete Description section.

@github-actions github-actions bot added the Missing info The user didn't precise the problem enough label May 30, 2024
@hoonjoo-park hoonjoo-park reopened this Aug 8, 2024
@hoonjoo-park
Copy link
Author

Setting detachInactiveScreens to false resolved the issue, However, this seems to be a workaround rather than addressing the root cause.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Missing info The user didn't precise the problem enough Missing repro This issue need minimum repro scenario Platform: iOS This issue is specific to iOS
Projects
None yet
Development

No branches or pull requests

1 participant