diff --git a/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java b/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java index eb1906ea9a4..7ac6b05e54b 100644 --- a/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java +++ b/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java @@ -4,6 +4,7 @@ import com.facebook.react.ReactApplication; import com.facebook.react.ReactNativeHost; +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; import com.facebook.react.soloader.OpenSourceMergedSoMapping; import com.facebook.soloader.SoLoader; import com.reactnativenavigation.react.ReactGateway; @@ -40,6 +41,9 @@ public void onCreate() { } catch (IOException e) { throw new RuntimeException(e); } + + DefaultNewArchitectureEntryPoint.load(); + reactGateway = createReactGateway(); } diff --git a/playground/android/app/build.gradle b/playground/android/app/build.gradle index e950fed9345..64fc0f7693d 100644 --- a/playground/android/app/build.gradle +++ b/playground/android/app/build.gradle @@ -1,5 +1,6 @@ apply plugin: "com.android.application" apply plugin: "com.facebook.react" +apply plugin: 'org.jetbrains.kotlin.android' react { root = file("../../../") @@ -48,6 +49,9 @@ android { signingConfig signingConfigs.release } } + kotlinOptions { + jvmTarget = '17' + } } dependencies { @@ -59,6 +63,7 @@ dependencies { implementation project(':react-native-fast-image') implementation project(':react-native-navigation') + implementation 'androidx.core:core-ktx:1.16.0' androidTestImplementation('com.wix:detox:+') { transitive = true } androidTestImplementation 'junit:junit:4.12' diff --git a/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainActivity.java b/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainActivity.java deleted file mode 100644 index 09f09d537e9..00000000000 --- a/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainActivity.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.reactnativenavigation.playground; - -import android.os.Bundle; -import android.view.View; -import android.widget.ImageView; - -import com.reactnativenavigation.NavigationActivity; - -import androidx.annotation.Nullable; - -public class MainActivity extends NavigationActivity { - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setSplashLayout(); - } - - private void setSplashLayout() { - ImageView img = new ImageView(this); - img.setImageDrawable(getDrawable(R.drawable.ic_android)); - setContentView(img); - } -} diff --git a/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainActivity.kt b/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainActivity.kt new file mode 100644 index 00000000000..fddd91ee973 --- /dev/null +++ b/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainActivity.kt @@ -0,0 +1,18 @@ +package com.reactnativenavigation.playground + +import android.os.Bundle +import android.widget.ImageView +import com.reactnativenavigation.NavigationActivity + +class MainActivity : NavigationActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setSplashLayout() + } + + private fun setSplashLayout() { + val img = ImageView(this) + img.setImageDrawable(getDrawable(R.drawable.ic_android)) + setContentView(img) + } +} diff --git a/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainApplication.java b/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainApplication.java deleted file mode 100644 index 75a3e30ca90..00000000000 --- a/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainApplication.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.reactnativenavigation.playground; - -import com.facebook.react.PackageList; -import com.facebook.react.ReactHost; -import com.facebook.react.ReactNativeHost; -import com.facebook.react.ReactPackage; -import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; -import com.facebook.react.defaults.DefaultReactHost; -import com.reactnativenavigation.NavigationApplication; -import com.reactnativenavigation.RNNToggles; -import com.reactnativenavigation.react.NavigationPackage; -import com.reactnativenavigation.react.NavigationReactNativeHost; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class MainApplication extends NavigationApplication { - - private final ReactNativeHost mReactNativeHost = - new NavigationReactNativeHost(this) { - @Override - protected String getJSMainModuleName() { - return "index"; - } - - @Override - public boolean getUseDeveloperSupport() { - return BuildConfig.DEBUG; - } - - @Override - public List getPackages() { - ArrayList packages = new PackageList(this).getPackages(); - packages.add(new NavigationPackage()); - return packages; - } - - @Override - protected Boolean isHermesEnabled() { - return BuildConfig.IS_HERMES_ENABLED; - } - - @Override - protected boolean isNewArchEnabled() { - return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; - } - }; - - public MainApplication() { - super(new HashMap<>() {{ - put(RNNToggles.TOP_BAR_COLOR_ANIMATION__PUSH, true); - put(RNNToggles.TOP_BAR_COLOR_ANIMATION__TABS, true); - }}); - } - - @Override - public void onCreate() { - super.onCreate(); - registerExternalComponent("RNNCustomComponent", new FragmentCreator()); - if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { - // If you opted-in for the New Architecture, we load the native entry point for this app. - DefaultNewArchitectureEntryPoint.load(); - } - } - - @Override - public ReactNativeHost getReactNativeHost() { - return mReactNativeHost; - } - - @Override - public ReactHost getReactHost() { - return DefaultReactHost.getDefaultReactHost(this, getReactNativeHost()); - } -} diff --git a/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainApplication.kt b/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainApplication.kt new file mode 100644 index 00000000000..7cba406ff7b --- /dev/null +++ b/playground/android/app/src/main/java/com/reactnativenavigation/playground/MainApplication.kt @@ -0,0 +1,46 @@ +package com.reactnativenavigation.playground + +import com.facebook.react.PackageList +import com.facebook.react.ReactHost +import com.facebook.react.ReactNativeHost +import com.facebook.react.ReactPackage +import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost +import com.reactnativenavigation.NavigationApplication +import com.reactnativenavigation.RNNToggles +import com.reactnativenavigation.react.NavigationPackage +import com.reactnativenavigation.react.NavigationReactNativeHost + +class MainApplication : NavigationApplication(mapOf( + RNNToggles.TOP_BAR_COLOR_ANIMATION__PUSH to true, + RNNToggles.TOP_BAR_COLOR_ANIMATION__TABS to true +)) { + override val reactNativeHost: ReactNativeHost = object : NavigationReactNativeHost(this) { + override fun getJSMainModuleName(): String { + return "index" + } + + override fun getUseDeveloperSupport(): Boolean { + return BuildConfig.DEBUG + } + + public override fun getPackages(): List { + val packages = PackageList(this).packages + packages.add(NavigationPackage()) + return packages + } + + override val isHermesEnabled: Boolean + get() = BuildConfig.IS_HERMES_ENABLED + + override val isNewArchEnabled: Boolean + get() = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED + } + + override fun onCreate() { + super.onCreate() + registerExternalComponent("RNNCustomComponent", FragmentCreator()) + } + + override val reactHost: ReactHost + get() = getDefaultReactHost(this, reactNativeHost) +} diff --git a/playground/android/build.gradle b/playground/android/build.gradle index 3f28b9fd98d..d61b3dad8e1 100644 --- a/playground/android/build.gradle +++ b/playground/android/build.gradle @@ -33,6 +33,7 @@ allprojects { flatDir { dirs "$rootProject.projectDir/libs" } + mavenCentral() } } diff --git a/website/docs/docs/docs-Installing.mdx b/website/docs/docs/docs-Installing.mdx index 8507ab47378..cbf37d47da4 100644 --- a/website/docs/docs/docs-Installing.mdx +++ b/website/docs/docs/docs-Installing.mdx @@ -6,8 +6,9 @@ sidebar_label: Installation ## Requirements -- node >= 8 -- react-native >= 0.51 +- node >= 18.18 +- react-native = 0.77 (0.78 - 0.80 support is in progress) +- new architecture enabled (if you are not using the new architecture, you can still use react-native-navigation of version 7.x.x with react-native 0.73 and lower) ## npm or yarn @@ -25,7 +26,7 @@ yarn add react-native-navigation ## Installing with `npx rnn-link` -If you're using RN 0.60 or higher, you can benefit from autolinking for some of the necessary installation steps. But unlike most other libraries, react-native-navigation requires you to make a few changes to native files. +You can benefit from autolinking for some of the necessary installation steps. But unlike most other libraries, react-native-navigation requires you to make a few changes to native files. We've simplified the process through a set of scripts. So to make all the necessary changes automatically, in your project's root folder run: @@ -33,7 +34,7 @@ We've simplified the process through a set of scripts. So to make all the necess Make sure to commit the changes introduced by the `rnn-link` script. -> The automatic linking is optimized for new applications created via the `react-native init` command. If you are migrating from a version of react-native-navigation older than v5, it's recommended to check the steps manually after the script runs. +> The automatic linking is optimized for new applications created via the `npx @react-native-community/cli@latest init` command. If you are migrating from a version of react-native-navigation older than v7, it's recommended to check the steps manually after the script runs. If one of the steps failed or you can't run (or are not comfortable with) the automatic scripts, you'll need to complete the relevant steps in the manual installation steps below, for both platforms. @@ -87,7 +88,7 @@ react-native run-android ``` :::tip -This is a good moment to build your application in both platforms, validate that everything is working properly and commit your changes. If you're coming from a fresh `react-native init` project, then you should be seeing the Welcome screen as usual, but under the hood your application is using react-native-navigation! +This is a good moment to build your application in both platforms, validate that everything is working properly and commit your changes. If you're coming from a fresh `npx @react-native-community/cli@latest init` project, then you should be seeing the Welcome screen as usual, but under the hood your application is using react-native-navigation! :::: --- @@ -98,248 +99,154 @@ If installation with `npx rnn-link` did not work, follow the manual installation ### iOS -> Make sure your Xcode is updated. We recommend editing `.h` and `.m` files in Xcode as the IDE will usually point out common errors. +> Make sure your Xcode is updated. We recommend editing `.h`, `.mm` and `.swift` files in Xcode as the IDE will usually point out common errors. #### Installation with CocoaPods -Projects generated using newer versions of react-native use CocoaPods by default. In that case it's easier to install react-native-navigation using CocoaPods. - -1. Update your `Podfile`: - **If you're upgrading to v5 from a previous RNN version**, make sure to remove manual linking of RNN - -```diff -platform :ios, '9.0' -require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' - -target 'YourApp' do - # Pods for YourApp - pod 'React', :path => '../node_modules/react-native/' - pod 'React-Core', :path => '../node_modules/react-native/React' - pod 'React-DevSupport', :path => '../node_modules/react-native/React' - pod 'React-fishhook', :path => '../node_modules/react-native/Libraries/fishhook' - pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' - pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' - pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' - pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' - pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' - pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' - pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' - pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' - pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' - pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket' - - pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' - pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' - pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' - pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' - pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga' - - pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' - pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' - pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' - -- pod 'ReactNativeNavigation', :podspec => '../node_modules/react-native-navigation/ReactNativeNavigation.podspec' - - use_native_modules! -end -``` - -2. `cd ios && pod install` +`cd ios && pod install` #### Native Installation -> If the React Native version in your project is above 0.60 and you are following the manual installation, skip to step 3. - -If autolinking is not available in your project (RN version < 0.60), you can always try and install the hardcore way: +> **Choose your implementation language**: Depending on whether your project uses Swift or Objective-C, follow the appropriate section below. Most new React Native projects use Swift by default. -1. In Xcode, in Project Navigator (left pane), right-click on the `Libraries` > `Add files to [project name]`. Add `node_modules/react-native-navigation/lib/ios/ReactNativeNavigation.xcodeproj` ([screenshots](https://facebook.github.io/react-native/docs/linking-libraries-ios.html#manual-linking)). +##### For Swift projects -2. In Xcode, in Project Navigator (left pane), click on your project (top), then click on your _target_ row (on the "project and targets list", which is on the left column of the right pane) and select the `Build Phases` tab (right pane). In the `Link Binary With Libraries` section add `libReactNativeNavigation.a` ([screenshots](https://facebook.github.io/react-native/docs/linking-libraries-ios.html#step-2)). +In Xcode, you will need to update this file: `AppDelegate.swift` -a. If you're seeing an error message in Xcode such as: +```swift +import UIKit +import React +- import React_RCTAppDelegate ++ import ReactNativeNavigation +import ReactAppDependencyProvider -``` -'ReactNativeNavigation/ReactNativeNavigation.h' file not found. -``` - -You may also need to add a Header Search Path: ([screenshots](https://facebook.github.io/react-native/docs/linking-libraries-ios.html#step-3)). - -```objectivec -$(SRCROOT)/../node_modules/react-native-navigation/lib/ios +@main +- class AppDelegate: RCTAppDelegate { ++ class AppDelegate: RNNAppDelegate { +... ``` -3. In Xcode, you will need to edit this file: `AppDelegate.m`. This function is the main entry point for your app: +##### For Objective-C projects -```objectivec - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... } -``` - -Its content should look like this: +In Xcode, you will need to edit this file: `AppDelegate.h`. Its content should look like this: ```objectivec -#import "AppDelegate.h" - -#import -#import -#import - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - [ReactNativeNavigation bootstrapWithDelegate:self launchOptions:launchOptions]; +#import +- #import ++ #import "RNNAppDelegate.h" - return YES; -} - -- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge -{ - #if DEBUG - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; - #else - return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; - #endif -} - -- (NSArray> *)extraModulesForBridge:(RCTBridge *)bridge { - return [ReactNativeNavigation extraModulesForBridge:bridge]; -} +- @interface AppDelegate : RCTAppDelegate ++ @interface AppDelegate : RNNAppDelegate @end -``` - a. If, in Xcode, you see the following error message in `AppDelegate.m` next to `#import "RCTBundleURLProvider.h"`: - ``` - ! 'RCTBundleURLProvider.h' file not found - ``` - This is because the `React` scheme is missing from your project. You can verify this by opening the `Product` menu and the `Scheme` submenu. - To make the `React` scheme available to your project, run `npm install -g react-native-git-upgrade` followed by `react-native-git-upgrade`. Once this is done, you can click back to the menu in Xcode: `Product -> Scheme -> Manage Schemes`, then click '+' to add a new scheme. From the `Target` menu, select "React", and click the checkbox to make the scheme `shared`. This should make the error disappear. +``` ### Android -> Make sure your Android Studio installation is up to date. We recommend editing `gradle` and `java` files in Android Studio as the IDE will suggest fixes and point out errors, this way you avoid most common pitfalls. +> Make sure your Android Studio installation is up to date. We recommend editing `gradle` and `kotlin` files in Android Studio as the IDE will suggest fixes and point out errors, this way you avoid most common pitfalls. #### 1 Update `android/build.gradle`: ```diff buildscript { - ext { -- minSdkVersion = 16 -+ minSdkVersion = 21 // Or higher - compileSdkVersion = 30 - targetSdkVersion = 30 -- supportLibVersion = "26.1.0" // use AndroidX when possible -+ kotlinVersion = "1.5.31" // Or any version above 1.4.x -+ RNNKotlinVersion = kotlinVersion - } + ext { + kotlinVersion = "2.0.21" ++ RNNKotlinVersion = kotlinVersion + compileSdkVersion = 35 + buildToolsVersion = "35.0.0" + minSdkVersion = 24 + targetSdkVersion = 34 + ndkVersion = "27.1.12297006" + } repositories { google() - jcenter() -+ mavenLocal() -+ mavenCentral() + mavenCentral() } dependencies { -+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") -+ classpath 'com.android.tools.build:gradle:4.0.1' // Or higher -- classpath 'com.android.tools.build:gradle:2.2.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" + classpath("com.facebook.react:react-native-gradle-plugin") + classpath 'com.android.tools.build:gradle' } } allprojects { repositories { -+ google() - mavenLocal() -- jcenter() -+ mavenCentral() + google() maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm url "$rootDir/../node_modules/react-native/android" } -- maven { -- url 'https://maven.google.com/' -- name 'Google' -- } -+ maven { url 'https://jitpack.io' } } } ``` -#### 2 Update `MainActivity.java` - -`MainActivity.java` should extend `com.reactnativenavigation.NavigationActivity` instead of `ReactActivity`. +#### 2 Update `MainActivity.kt` -This file is located in `android/app/src/main/java/com//MainActivity.java`. ```diff --import com.facebook.react.ReactActivity; -+import com.reactnativenavigation.NavigationActivity; - --public class MainActivity extends ReactActivity { -+public class MainActivity extends NavigationActivity { -- @Override -- protected String getMainComponentName() { -- return "yourproject"; +-import com.facebook.react.ReactActivity ++import com.reactnativenavigation.NavigationActivity + +-class MainActivity : ReactActivity() { +- override fun getMainComponentName(): String { +- return "yourproject" - } -} +-} ++class MainActivity : NavigationActivity() ``` If you have any **react-native** related methods, you can safely delete them. -#### 3 Update `MainApplication.java` +#### 3 Update `MainApplication.kt` This file is located in `android/app/src/main/java/com//MainApplication.java`. ```diff ... -import android.app.Application; - -import com.facebook.react.ReactApplication; -import com.facebook.react.ReactNativeHost; -import com.facebook.react.ReactPackage; -import com.facebook.react.shell.MainReactPackage; -import com.facebook.soloader.SoLoader; - -+import com.reactnativenavigation.NavigationApplication; -+import com.reactnativenavigation.react.NavigationReactNativeHost; - --public class MainApplication extends Application implements ReactApplication { -+public class MainApplication extends NavigationApplication { - -private final ReactNativeHost mReactNativeHost = -- new ReactNativeHost(this) { -+ new NavigationReactNativeHost(this) { - @Override - public boolean getUseDeveloperSupport() { - return BuildConfig.DEBUG; - } - @Override - protected List getPackages() { - @SuppressWarnings("UnnecessaryLocalVariable") - List packages = new PackageList(this).getPackages(); - // Packages that cannot be autolinked yet can be added manually here, for example: - // packages.add(new MyReactNativePackage()); - return packages; - } +import com.facebook.react.PackageList +import com.facebook.react.ReactHost +import com.facebook.react.ReactNativeHost +import com.facebook.react.ReactPackage +import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost +import com.reactnativenavigation.NavigationApplication +import com.reactnativenavigation.react.NavigationPackage +import com.reactnativenavigation.react.NavigationReactNativeHost - @Override - protected String getJSMainModuleName() { - return "index"; - } - }; +class MainApplication : NavigationApplication() { + override val reactNativeHost: ReactNativeHost = +- object : DefaultReactNativeHost(this) { ++ object : NavigationReactNativeHost(this) { - @Override - public ReactNativeHost getReactNativeHost() { - return mReactNativeHost; - } + override fun getPackages(): List = + PackageList(this).packages.apply { + // Packages that cannot be autolinked yet can be added manually here, for example: + // add(MyReactNativePackage()) + } - @Override - public void onCreate() { - super.onCreate(); -- SoLoader.init(this, /* native exopackage */ false); - initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); - } + override fun getJSMainModuleName(): String = "index" + + override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG + + override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED + + override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED + } + + override val reactHost: ReactHost + get() = getDefaultReactHost(this, reactNativeHost) + + override fun onCreate() { + super.onCreate() +- SoLoader.init(this, OpenSourceMergedSoMapping) +- if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { +- // If you opted-in for the New Architecture, we load the native entry point for this app. +- load() +- } + } } + ``` ### App root @@ -396,3 +303,6 @@ dependencies { } ``` + +``` +```