使用 react-native-splash-screen 时如何重构 AppDelegate.m 以仅加载应用程序一次?

Posted

技术标签:

【中文标题】使用 react-native-splash-screen 时如何重构 AppDelegate.m 以仅加载应用程序一次?【英文标题】:How to refactor AppDelegate.m to only load app once when using react-native-splash-screen? 【发布时间】:2020-12-19 05:23:55 【问题描述】:

似乎在 ios react-native-splash-screen 上会导致应用程序的 javascript 运行两次。这会在应用程序的初始加载逻辑期间导致问题。例如,我无法检测到应用程序是否被通知打开,因为第一次加载读取了通知,然后第二次加载找不到它。

我发现这个 Github issue 关于同样的问题,但由于我使用的是更新版本的 React Native,我不确定如何将应用程序在 iOS 上的加载重构为只执行一次。 https://github.com/wix/react-native-navigation/issues/5016

闪屏包的实现可以看这个Githubhttps://github.com/crazycodeboy/react-native-splash-screen/blob/master/ios/RNSplashScreen.m

我真的不熟悉 iOS 端如何在 React 中工作。任何帮助表示赞赏。

AppDelegate.m

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <Firebase.h>
#import "RNSplashScreen.h"
#import <GoogleMaps/GoogleMaps.h>

#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.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

  #ifdef FB_SONARKIT_ENABLED
    InitializeFlipper(application);
  #endif
  [GMSServices provideAPIKey:@"[redacted]"];
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"PartyMe"
                                            initialProperties:nil];
  
  if ([FIRApp defaultApp] == nil) 
    [FIRApp configure];
  

  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];
  [RNSplashScreen show];
  return YES;


- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge

#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif


@end

编辑 我试图通过注释掉所有默认的 React Native 加载代码来更新文件。 (我知道,长镜头。)应用程序加载了初始屏幕,但看起来应用程序从未真正执行过 - 这是有道理的。

【问题讨论】:

【参考方案1】:

我的解决方案是使用 react-native-bootsplash 而不是 react-native-splash-screen。

https://github.com/zoontek/react-native-bootsplash

【讨论】:

以上是关于使用 react-native-splash-screen 时如何重构 AppDelegate.m 以仅加载应用程序一次?的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)