react-native 在RN >= 0.74版本中,应用场景委托得到了支持,

ruarlubt  于 22天前  发布在  React
关注(0)|答案(5)|浏览(23)

当我们为我们的React Native应用添加CarPlay支持时,我们需要从App Delegate to Application Scene Delegates切换。无论应用程序是在手机上启动(PhoneScene)还是在CarPlay客户端上启动(CarScene),首先运行的本地代码始终是AppDelegates application:didFinishLaunchingWithOptions:方法。
一个React Native应用通常在其AppDelegate中调用超类方法,该方法在React Native自己的RCTAppDelegate中实现。这个问题在于RCTAppDelegate假定了手机的使用,并为应用程序创建了一个rootViewController以及一个窗口来显示其视图。这导致了在首先在CarPlay客户端上启动应用程序时出现问题,因为CarPlay不需要根视图控制器或窗口来显示其视图。
解决这个问题的关键是将应用程序初始化逻辑拆分为PhoneScene和CarScene(它们都是UIResponder的子类),并仅在AppDelegate中运行设置React Native桥接所需的代码。我们可以通过不在application:didFinishLaunchingWithOptions:中调用超类方法而是创建并调用自定义init方法来实现这一点。
在React Native 0.74之前,这不是一个问题,因为所有需要设置的方法都是公开暴露的。从React Native 0.74开始,通过RCTRootViewFactory创建根视图,而无法从App Delegate中的自定义初始化例程示例化一个。
你打算如何在将来支持Application Scene Delegates?有没有在不按照此处描述的方式修补头文件的情况下创建RCTRootViewFactory的选项?将createRCTRootViewFactory暴露在头文件中会不会有问题,使其可以从App Delegate中访问?

重现步骤

尝试通过application scene delegates设置一个RN 0.74或0.75应用程序

React Native版本

0.74

受影响的平台

运行时-iOS

npx react-native info的输出

irrelevant

堆栈跟踪或日志

none

重现器

截图和视频

  • 无响应*
bqujaahr

bqujaahr1#

⚠️添加或重新格式化版本信息
i️我们无法在您的问题报告中找到或解析React Native的版本号。请使用此模板,并报告您的版本,包括主要、次要和补丁编号 - 例如:0.70.2
e5nszbig

e5nszbig2#

⚠️缺失可复现示例
i️我们无法在您的问题报告中检测到可复现的示例。请提供以下内容:* 如果您的错误与UI相关:一个 Snack* 如果您的错误与构建/更新相关:使用我们的 Reproducer Template 。需要在您用户名下的GitHub仓库中有一个复现器。
fhg3lkii

fhg3lkii3#

⚠️缺失可复现示例
i️我们无法在您的问题报告中检测到可复现的示例。请提供以下内容:* 如果您的错误与UI相关:一个 Snack* 如果您的错误与构建/更新相关:使用我们的 Reproducer Template
vu8f3i0k

vu8f3i0k4#

⚠️添加或重新格式化版本信息
i️我们无法在您的问题报告中找到或解析React Native的版本号。请使用此模板,并报告您的版本,包括主要、次要和补丁编号 - 例如:0.70.2
eagi6jfj

eagi6jfj5#

嘿,
我最初是在实现RCTRootViewFactory,其目标是解决您正在遇到的问题。
如果您想完全重构React Native的初始化流程,那么您可以使用这个类来按照您想要的方式进行初始化。根视图工厂封装了在RN 0.74之前必须手动编写的逻辑。
为Scene Delegate添加支持是一回事(我认为我们应该有一天解决这个问题),但如果您现在想使用它,可以这样做:

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions {
  
  // Create configuration
 RCTRootViewFactoryConfiguration *configuration = [[RCTRootViewFactoryConfiguration alloc] initWithBundleURL:self.bundleURL 
                                                                                                 newArchEnabled:self.fabricEnabled
                                                                                             turboModuleEnabled:self.turboModuleEnabled
                                                                                              bridgelessEnabled:self.bridgelessEnabled];

// Use blocks to pass callbacks
configuration.sourceURLForBridge = ^NSURL *_Nullable(RCTBridge *_Nonnull bridge)
  {
    
  };
  
  // Initialize RCTRootViewFactory
  self.rootViewFactory = [[RCTRootViewFactory alloc] initWithConfiguration:configuration];
  
  // Create main root view
  UIView *rootView = [self.rootViewFactory viewWithModuleName:@"RNTesterApp" initialProperties:@{} launchOptions:launchOptions];

  
  // Set main window as you prefer for your Brownfield integration.
  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  
  // Later in the codebase you can initialize more rootView's using rootViewFactory.
  
  return YES;
}
@end

您可以轻松地将上述代码重构为适应Scene delegate模式。

相关问题