diff --git a/native/.gitignore b/native/.gitignore --- a/native/.gitignore +++ b/native/.gitignore @@ -20,6 +20,7 @@ *.hmap *.ipa *.xcuserstate +ios/.xcode.env.local # Android/IntelliJ # diff --git a/native/ios/.xcode.env b/native/ios/.xcode.env new file mode 100644 --- /dev/null +++ b/native/ios/.xcode.env @@ -0,0 +1,10 @@ +# This `.xcode.env` file is versioned and is used to source the environment +# used when running script phases inside Xcode. +# To customize your local environment, you can create an `.xcode.env.local` +# file that is not versioned. +# NODE_BINARY variable contains the PATH to the node executable. +# +# Customize the NODE_BINARY variable here. +# For example, to use nvm with brew, add the following line +# . "$(brew --prefix nvm)/nvm.sh" --no-use +export NODE_BINARY=$(command -v node) diff --git a/native/ios/Comm.xcodeproj/project.pbxproj b/native/ios/Comm.xcodeproj/project.pbxproj --- a/native/ios/Comm.xcodeproj/project.pbxproj +++ b/native/ios/Comm.xcodeproj/project.pbxproj @@ -758,13 +758,15 @@ files = ( ); inputPaths = ( + "$(SRCROOT)/.xcode.env.local", + "$(SRCROOT)/.xcode.env", ); name = "Bundle React Native code and images"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n"; + shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; }; 02DE093B3C1DDF10C1FA3E9C /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; @@ -1012,7 +1014,7 @@ baseConfigurationReference = F53DA7B3F26C2798DCE74A94 /* Pods-Comm.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_ENABLE_MODULES = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES; CODE_SIGN_ENTITLEMENTS = Comm/Comm.entitlements; @@ -1034,9 +1036,10 @@ "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS", "$(PODS_ROOT)/boost-for-react-native", "$(SRCROOT)/../native_rust_library", + "$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging", ); INFOPLIST_FILE = Comm/Info.debug.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1138,7 +1141,7 @@ "-DFOLLY_MOBILE=1", "-DFOLLY_NO_CONFIG", "-DFOLLY_USE_LIBCPP=1", - "-DRNVERSION=63", + "-DRNVERSION=70", "-fcxx-modules", "-fmodules", ); @@ -1164,7 +1167,7 @@ baseConfigurationReference = C562A7004903539402D988CE /* Pods-Comm.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_ENABLE_MODULES = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES; CODE_SIGN_ENTITLEMENTS = Comm/Comm.entitlements; @@ -1179,9 +1182,10 @@ "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS", "$(PODS_ROOT)/boost-for-react-native", "$(SRCROOT)/../native_rust_library", + "$(PODS_ROOT)/Headers/Private/React-bridging/react/bridging", ); INFOPLIST_FILE = Comm/Info.release.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1275,7 +1279,7 @@ "-DFOLLY_MOBILE=1", "-DFOLLY_NO_CONFIG", "-DFOLLY_USE_LIBCPP=1", - "-DRNVERSION=63", + "-DRNVERSION=70", "-fcxx-modules", "-fmodules", ); @@ -1302,7 +1306,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; @@ -1344,7 +1348,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; @@ -1382,7 +1386,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; @@ -1404,7 +1408,7 @@ INFOPLIST_FILE = NotificationService/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = NotificationService; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 Comm Technologies, Inc. All rights reserved."; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1439,7 +1443,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; @@ -1458,7 +1462,7 @@ INFOPLIST_FILE = NotificationService/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = NotificationService; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 Comm Technologies, Inc. All rights reserved."; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1534,9 +1538,17 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-DFOLLY_MOBILE=1", + "-DFOLLY_NO_CONFIG", + "-DFOLLY_USE_LIBCPP=1", + "-fcxx-modules", + "-fmodules", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; @@ -1583,8 +1595,16 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; MTL_ENABLE_DEBUG_INFO = NO; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-DFOLLY_MOBILE=1", + "-DFOLLY_NO_CONFIG", + "-DFOLLY_USE_LIBCPP=1", + "-fcxx-modules", + "-fmodules", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/native/ios/Comm/AppDelegate.mm b/native/ios/Comm/AppDelegate.mm --- a/native/ios/Comm/AppDelegate.mm +++ b/native/ios/Comm/AppDelegate.mm @@ -1,12 +1,35 @@ #import "AppDelegate.h" -#import "Orientation.h" -#import "RNNotifications.h" #import #import -#import #import +#import + +#if RCT_NEW_ARCH_ENABLED +#import +#import +#import +#import +#import +#import +#import +static NSString *const kRNConcurrentRoot = @"concurrentRoot"; +@interface AppDelegate () < + RCTCxxBridgeDelegate, + RCTTurboModuleManagerDelegate> { + RCTTurboModuleManager *_turboModuleManager; + RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; + std::shared_ptr _reactNativeConfig; + facebook::react::ContextContainer::Shared _contextContainer; +} +@end +#endif + +#import "Orientation.h" +#import "RNNotifications.h" +#import + #import #import #import @@ -26,28 +49,6 @@ #import #import -#ifdef FB_SONARKIT_ENABLED -#import -#import -#import -#import -#import -#import -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 - #import #import @@ -73,17 +74,30 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { -#ifdef FB_SONARKIT_ENABLED - InitializeFlipper(application); -#endif + RCTAppSetupPrepareApp(application); + [self moveMessagesToDatabase]; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil]; + RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; - RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge - moduleName:@"Comm" - initialProperties:nil]; + +#if RCT_NEW_ARCH_ENABLED + _contextContainer = + std::make_shared(); + _reactNativeConfig = + std::make_shared(); + _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); + _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] + initWithBridge:bridge + contextContainer:_contextContainer]; + bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; +#endif + + NSDictionary *initProps = [self prepareInitialProps]; + UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"Comm", initProps); + if (@available(iOS 13.0, *)) { rootView.backgroundColor = [UIColor systemBackgroundColor]; } else { @@ -104,9 +118,10 @@ bundle:nil] instantiateInitialViewController] .view; launchScreenView.frame = self.window.bounds; - rootView.loadingView = launchScreenView; - rootView.loadingViewFadeDelay = 0; - rootView.loadingViewFadeDuration = 0.001; + + ((RCTRootView *)rootView).loadingView = launchScreenView; + ((RCTRootView *)rootView).loadingViewFadeDelay = 0; + ((RCTRootView *)rootView).loadingViewFadeDuration = 0.001; return YES; } @@ -117,6 +132,26 @@ return @[]; } +/// This method controls whether the `concurrentRoot`feature of React18 is +/// turned on or off. +/// +/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html +/// @note: This requires to be rendering on Fabric (i.e. on the New +/// Architecture). +/// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it +/// returns `false`. +- (BOOL)concurrentRootEnabled { + // Switch this bool to turn on and off the concurrent root + return true; +} +- (NSDictionary *)prepareInitialProps { + NSMutableDictionary *initProps = [NSMutableDictionary new]; +#ifdef RCT_NEW_ARCH_ENABLED + initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]); +#endif + return initProps; +} + - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [RNNotifications @@ -198,14 +233,43 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG return - [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" - fallbackResource:nil]; + [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } +#if RCT_NEW_ARCH_ENABLED +#pragma mark - RCTCxxBridgeDelegate +- (std::unique_ptr) + jsExecutorFactoryForBridge:(RCTBridge *)bridge { + _turboModuleManager = + [[RCTTurboModuleManager alloc] initWithBridge:bridge + delegate:self + jsInvoker:bridge.jsCallInvoker]; + return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager); +} +#pragma mark RCTTurboModuleManagerDelegate +- (Class)getModuleClassFromName:(const char *)name { + return RCTCoreModulesClassProvider(name); +} +- (std::shared_ptr) + getTurboModule:(const std::string &)name + jsInvoker:(std::shared_ptr)jsInvoker { + return nullptr; +} +- (std::shared_ptr) + getTurboModule:(const std::string &)name + initParams: + (const facebook::react::ObjCTurboModule::InitParams &)params { + return nullptr; +} +- (id)getModuleInstanceFromClass:(Class)moduleClass { + return RCTAppSetupDefaultModuleFromClass(moduleClass); +} +#endif + using JSExecutorFactory = facebook::react::JSExecutorFactory; using HermesExecutorFactory = facebook::react::HermesExecutorFactory; using Runtime = facebook::jsi::Runtime;