facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.8k stars 24.29k forks source link

What is the standard procedure/way to convert AppDelegate.m to AppDelegate.mm? #38780

Closed AdarshJais closed 1 year ago

AdarshJais commented 1 year ago

New Version

0.72.3

Old Version

0.67.5

Build Target(s)

iOS

Output of react-native info

System: OS: macOS 13.2.1 CPU: (8) arm64 Apple M2 Memory: 79.05 MB / 8.00 GB Shell: version: 5.8.1 path: /bin/zsh Binaries: Node: version: 20.5.0 path: /opt/homebrew/bin/node Yarn: version: 1.22.19 path: /usr/local/bin/yarn npm: version: 9.8.0 path: /opt/homebrew/bin/npm Watchman: version: 2023.07.24.00 path: /opt/homebrew/bin/watchman Managers: CocoaPods: version: 1.11.3 path: /Users/adarshjaiswal/.rvm/gems/ruby-2.7.5/bin/pod SDKs: iOS SDK: Not Found Android SDK: API Levels:

Issue and Reproduction Steps

The upgrade helper link state that (https://react-native-community.github.io/upgrade-helper/?from=0.67.5&to=0.72.3) We should change AppDelegate.m to AppDelegate.mm.

I want to know shall we just change the .m to .mm and it will work (which I feel is not the case) or We should create a new file. If we need to create the new one how we are going to handle the existing code that we have inside the AppDelegate.m file (I am not much aware of ios development)?

For me here is the AppDelgate.m file:

#import "AppDelegate.h"
#import <AppCenterReactNative.h>
#import <AppCenterReactNativeAnalytics.h>
#import <AppCenterReactNativeCrashes.h>

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import<ReactNativeMoEngage/MoEngageInitializer.h>
#import <React/RCTLinkingManager.h>
#import <CodePush/CodePush.h>
#import <Firebase.h>
#import <TrustKit/TrustKit.h>
#import <TrustKit/TSKPinningValidator.h>
#import <TrustKit/TSKPinningValidatorCallback.h>
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
#import "RNSplashScreen.h"

#ifdef FB_SONARKIT_ENABLED
@import MoEngageSDK;
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
{

  // Set Data Center
  [[MoEngageInitializer sharedInstance] initializeDefaultInstance: launchOptions];
#ifdef FB_SONARKIT_ENABLED
  InitializeFlipper(application);
#endif
  //SSL pinning implementation
  void (^loggerBlock)(NSString *) = ^void(NSString *message)
   {
     NSLog(@"TrustKit log: %@", message);
   };
   [TrustKit setLoggerBlock:loggerBlock];

   NSDictionary *trustKitConfig =
   @{
     // Swizzling because we can't access the NSURLSession instance used in React Native's fetch method
     kTSKSwizzleNetworkDelegates: @YES,
     kTSKPinnedDomains: @{
         @"MyApp.com" : @{
             kTSKIncludeSubdomains: @YES, // Pin all subdomains
             kTSKEnforcePinning: @NO, // Block connections if pinning validation failed
             kTSKDisableDefaultReportUri: @YES,
             kTSKPublicKeyHashes : @[
               @"yQp8H58o___________________ChvX/CPtQ=",
               @"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=", // Fake backup key but we need to provide 2 pins
             ],
         },
     }};
   [TrustKit initSharedInstanceWithConfiguration:trustKitConfig];
   [TrustKit sharedInstance].pinningValidatorCallback = ^(TSKPinningValidatorResult *result, NSString *notedHostname, TKSDomainPinningPolicy *policy) {
     if (result.finalTrustDecision == TSKTrustEvaluationFailedNoMatchingPin) {
       NSLog(@"TrustKit certificate matching failed");
       // Add more logging here. i.e. Sentry, BugSnag etc
     }
   };
  [FIRApp configure];
  [AppCenterReactNative register];
  [AppCenterReactNativeAnalytics registerWithInitiallyEnabled:true];
  [AppCenterReactNativeCrashes registerWithAutomaticProcessing];

  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"MyAppTesting"
                                            initialProperties:nil];
  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];

  if (@available(iOS 13.0, *)) {
      rootView.backgroundColor = [UIColor systemBackgroundColor];
  } else {
      rootView.backgroundColor = [UIColor whiteColor];
  }
  if (@available(iOS 14, *)) {
    UIDatePicker *picker = [UIDatePicker appearance];
    picker.preferredDatePickerStyle = UIDatePickerStyleWheels;
  }
  if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://com.MyApp.Testing"]]){
    exit(0);
  }

  // Always keep this before return YES or atleast after [self.window makeKeyAndVisible];, else app will stuck on splash screen
  [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"];
  return [CodePush bundleURL];
#endif
}
// code for app switcher configuration , reading the app when its going to background and reading it back when its coming to foreground
- (void)applicationWillResignActive:(UIApplication *)application {
    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    [blurEffectView setFrame:self.window.bounds];
    blurEffectView.tag = 1234;
    blurEffectView.alpha = 0;
    [self.window addSubview:blurEffectView];
    [self.window bringSubviewToFront:blurEffectView];
    [UIView animateWithDuration:0.5 animations:^{
        blurEffectView.alpha = 1;
    }];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    UIVisualEffectView *blurEffectView = [self.window viewWithTag:1234];
    [UIView animateWithDuration:0.5 animations:^{
      blurEffectView.alpha = 0;
    } completion:^(BOOL finished) {
        [blurEffectView removeFromSuperview];
    }];
}
- (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

In case I just delete my AppDelegate.m file completely and add AppDelegate.mm that is mentioned inside the upgrade helper link, I get the error 9 Duplicate symbols for architecture x86_64

github-actions[bot] commented 1 year ago
:warning: Missing Reproducible Example
:information_source: We could not detect a reproducible example in your issue report. Please provide either:
  • If your bug is UI related: a Snack
  • If your bug is build/update related: use our Reproducer Template. A reproducer needs to be in a GitHub repository under your username.
cipolleschi commented 1 year ago

Hi there!

I want to know shall we just change the .m to .mm and it will work (which I feel is not the case) or We should create a new file. If we need to create the new one how we are going to handle the existing code that we have inside the AppDelegate.m file (I am not much aware of ios development)?

Yes, but only if you rename it from within Xcode

In case I just delete my AppDelegate.m file completely and add AppDelegate.mm that is mentioned inside the upgrade helper link, I get the error 9 Duplicate symbols for architecture x86_64 Also, I have ignored the change mentioned for project.pbxproj in the upgrade helper link, assuming that it will be autogenerated while building project. (Am I correct here?)

No, you shouldn't have ignored that. The project.pbxproj is not automatically generated and it has an "hardcoded" list of filenames that uses to generate the project. Xcode takes care of keeping them in sync, so when you rename a file in Xcode, the project.pbxproj is updated correctly.

Deleting the .m and recreating the .mm is unlikely to work.


The smoothest and quickest way to do it is:

The last step needs to be done in Xcode because otherwise Xcode is not aware of the rename (it doesn't look at the file system to create the project.)

The two files are exactly the same. The .mm is needed to actually use and import C++ files, but functionally, can be exactly the same as the .m file.

Then, if you want to simplify your AppDelegate furthermore and have an easier time with future updates, you can look at the RCTAppDelegate class.

Ideally the steps are:

You can use the template AppDelegate.h and AppDelegate.mm files as an example of what the final situation should be.

AdarshJais commented 1 year ago

Followed every step and again finally stuck on the same issue.

9 duplicate symbols for architecture x86_64

cipolleschi commented 1 year ago

It's a little hard to help out without knowing which symbols are. A couple of tricks: