【问题标题】:React Native 0.66 iOS crashes on AppDelegate RCTRootView initReact Native 0.66 iOS 在 AppDelegate RCTRootView 初始化时崩溃
【发布时间】:2021-12-01 09:29:47
【问题描述】:

我正在尝试将我们的 RN 项目升级到 0.66(从 0.63)。当我在调试模式下构建项目时,由于 uncaught exception 'NSInvalidArgumentException', reason: '-[REAEventDispatcher setBridge:]: unrecognized selector sent to instance 0x600002f51cc0' 在初始化 AppDelegate.m 文件中的 RCTRootView (最后是整个文件)时,应用程序在启动时崩溃。

经过一番谷歌搜索,我发现unrecognized selector 位是因为某个对象上的某些函数未定义。错误在代码中被标记,大约是文件的一半。

我需要一些帮助来找出为什么这个功能不可用(或者还有什么问题)。据我所见,这些文件具有被调用函数的实现。我错过了任何进口吗?对 Swift 不太熟悉,只和 React Native 结合使用。

我没有做一个可重现的例子,但我希望其他人已经在移植到这个版本时遇到了这个问题。如果您需要更多信息,请询问。我还在相关文件下方附加了 podfile。

Appdelegate.m

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>

#import "RNBootSplash.h"
#import <GoogleMaps/GoogleMaps.h>

#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>

#import <Firebase.h>


#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>

static void InitializeFlipper(UIApplication *application) {
  FlipperClient *client = [FlipperClient sharedClient];
  SKDescriptorMapper *layoutDescriptorMapper =
      [[SKDescriptorMapper alloc] initWithDefaults];
  [client addPlugin:[[FlipperKitLayoutPlugin alloc]
                            initWithRootNode:application
                        withDescriptorMapper:layoutDescriptorMapper]];
  [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
  [client addPlugin:[FlipperKitReactPlugin new]];
  [client addPlugin:[[FlipperKitNetworkPlugin alloc]
                        initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
  [client start];
}
#endif

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  if([FIRApp defaultApp] == nil){
    [FIRApp configure];
  }

   [GMSServices provideAPIKey:@"AIzaSyC-BV0Dp46BQ1iP1HRws-oP_90FV0Aewfo"]; // add this line using the api key obtained from Google Console

#ifdef FB_SONARKIT_ENABLED
  InitializeFlipper(application);
#endif

  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]
  //This is where the application crashes
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 
                                                   moduleName:@"Flatz"
                                            initialProperties:nil];
  
  if (@available(iOS 13.0, *)) {
      rootView.backgroundColor = [UIColor systemBackgroundColor];
  } else {
      rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f
                                                      green:1.0f
                                                       blue:1.0f
                                                      alpha:1];
  }

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];

  [RNBootSplash initWithStoryboard:@"LaunchScreen" rootView:rootView]; // <- initialization using the storyboard file name

  // Define UNUserNotificationCenter
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;

  return YES;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
#ifdef FB_SONARKIT_ENABLED
  return
      [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"
                                                     fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main"
                                 withExtension:@"jsbundle"];
#endif
}

// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
 [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
  [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
 [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler
{
  [RNCPushNotificationIOS didReceiveNotificationResponse:response];
}

//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}


- (BOOL)application:(UIApplication *)application
   openURL:(NSURL *)url
   options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
  return [RCTLinkingManager application:application openURL:url options:options];
}


- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
 restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
 return [RCTLinkingManager application:application
                  continueUserActivity:userActivity
                    restorationHandler:restorationHandler];
}

@end

Podfile

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '11.0'

target 'Flatz' do

  # No individual tracking of people or their phones
  $RNFirebaseAnalyticsWithoutAdIdSupport=true

  # React Native Maps dependencies
  rn_maps_path = '../node_modules/react-native-maps'
  pod 'react-native-google-maps', :path => rn_maps_path
  pod 'GoogleMaps'
  pod 'Google-Maps-iOS-Utils'

  config = use_native_modules!

  use_react_native!(
    :path => config["reactNativePath"],
    :hermes_enabled => true
  )


  target 'FlatzTests' do
    inherit! :complete
    # Pods for testing
  end

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable these next few lines.
  use_flipper!({ 'Flipper-Folly' => '2.5.3', 'Flipper' => '0.87.0', 'Flipper-RSocket' => '1.3.1' })

  post_install do |installer|
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        #1
        deployment_target = config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']
          #2
          target_components = deployment_target.split
            #3
            if target_components.length > 0
              #4
              target_initial = target_components[0].to_i
                #5
                if target_initial < 9
                  config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = "9.0"
                end
            end
        end
     end

     installer.pods_project.build_configurations.each do |config|
         config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
     end
  end

   permissions_path = '../node_modules/react-native-permissions/ios'
    pod 'Permission-Camera', :path => "#{permissions_path}/Camera"
end

【问题讨论】:

  • 您是否按照 RN Upgrade Helper 的说明从 0.63 过渡到 0.66?
  • 我不知道那是一回事。做完之后我会回来检查的。谢谢!

标签: ios swift react-native react-native-ios


【解决方案1】:

正如 jnpdx 指出的那样,我需要关注upgrade helper。事实证明,没有它,我错过了很多步骤。

【讨论】:

    猜你喜欢
    • 2018-03-15
    • 1970-01-01
    • 2019-06-01
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多