diff --git a/template/.bundle/config b/template/.bundle/config
deleted file mode 100644
index d137d242..00000000
--- a/template/.bundle/config
+++ /dev/null
@@ -1,2 +0,0 @@
-BUNDLE_PATH: "vendor/bundle"
-BUNDLE_FORCE_RUBY_PLATFORM: 1
\ No newline at end of file
diff --git a/template/.ruby-version b/template/.ruby-version
deleted file mode 100644
index 74500cee..00000000
--- a/template/.ruby-version
+++ /dev/null
@@ -1 +0,0 @@
-2.7.4
\ No newline at end of file
diff --git a/template/Gemfile b/template/Gemfile
index c72a1ae2..2c3edcf4 100644
--- a/template/Gemfile
+++ b/template/Gemfile
@@ -1,4 +1,6 @@
source 'https://rubygems.org'
+
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby '2.7.4'
+
gem 'cocoapods', '~> 1.11', '>= 1.11.2'
diff --git a/template/Gemfile.lock b/template/Gemfile.lock
index b354433d..88c2fa28 100644
--- a/template/Gemfile.lock
+++ b/template/Gemfile.lock
@@ -45,7 +45,7 @@ GEM
public_suffix (~> 4.0)
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.5)
- cocoapods-downloader (1.5.1)
+ cocoapods-downloader (1.6.1)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.1)
@@ -54,7 +54,7 @@ GEM
netrc (~> 0.11)
cocoapods-try (1.2.0)
colored2 (3.1.2)
- concurrent-ruby (1.1.9)
+ concurrent-ruby (1.1.10)
escape (0.0.4)
ethon (0.15.0)
ffi (>= 1.15.0)
@@ -86,11 +86,15 @@ GEM
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
zeitwerk (2.5.4)
+
PLATFORMS
ruby
+
DEPENDENCIES
cocoapods (~> 1.11, >= 1.11.2)
+
RUBY VERSION
ruby 2.7.4p191
+
BUNDLED WITH
- 2.2.27
\ No newline at end of file
+ 2.2.27
diff --git a/template/_bundle/config b/template/_bundle/config
new file mode 100644
index 00000000..848943bb
--- /dev/null
+++ b/template/_bundle/config
@@ -0,0 +1,2 @@
+BUNDLE_PATH: "vendor/bundle"
+BUNDLE_FORCE_RUBY_PLATFORM: 1
diff --git a/template/_gitignore b/template/_gitignore
index cc53454e..81570d99 100644
--- a/template/_gitignore
+++ b/template/_gitignore
@@ -56,5 +56,6 @@ buck-out/
# Bundle artifact
*.jsbundle
-# CocoaPods
+# Ruby / CocoaPods
/ios/Pods/
+/vendor/bundle/
diff --git a/template/_prettierrc.js b/template/_prettierrc.js
index 84196d95..2b540746 100644
--- a/template/_prettierrc.js
+++ b/template/_prettierrc.js
@@ -1,7 +1,7 @@
module.exports = {
+ arrowParens: 'avoid',
+ bracketSameLine: true,
bracketSpacing: false,
- jsxBracketSameLine: true,
singleQuote: true,
trailingComma: 'all',
- arrowParens: 'avoid',
};
diff --git a/template/_ruby-version b/template/_ruby-version
new file mode 100644
index 00000000..a4dd9dba
--- /dev/null
+++ b/template/_ruby-version
@@ -0,0 +1 @@
+2.7.4
diff --git a/template/android/app/build.gradle b/template/android/app/build.gradle
index a461d9a9..a173c56b 100644
--- a/template/android/app/build.gradle
+++ b/template/android/app/build.gradle
@@ -121,9 +121,12 @@ def jscFlavor = 'org.webkit:android-jsc:+'
def enableHermes = project.ext.react.get("enableHermes", false);
/**
- * Architectures to build native code for in debug.
+ * Architectures to build native code for.
*/
-def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")
+def reactNativeArchitectures() {
+ def value = project.getProperties().get("reactNativeArchitectures")
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
+}
android {
ndkVersion rootProject.ext.ndkVersion
@@ -136,13 +139,76 @@ android {
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
+
+ if (isNewArchitectureEnabled()) {
+ // We configure the NDK build only if you decide to opt-in for the New Architecture.
+ externalNativeBuild {
+ ndkBuild {
+ arguments "APP_PLATFORM=android-21",
+ "APP_STL=c++_shared",
+ "NDK_TOOLCHAIN_VERSION=clang",
+ "GENERATED_SRC_DIR=$buildDir/generated/source",
+ "PROJECT_BUILD_DIR=$buildDir",
+ "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
+ "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build"
+ cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
+ cppFlags "-std=c++17"
+ // Make sure this target name is the same you specify inside the
+ // src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
+ targets "helloworld_appmodules"
+ }
+ }
+ }
+ }
+
+ if (isNewArchitectureEnabled()) {
+ // We configure the NDK build only if you decide to opt-in for the New Architecture.
+ externalNativeBuild {
+ ndkBuild {
+ path "$projectDir/src/main/jni/Android.mk"
+ }
+ }
+ def reactAndroidProjectDir = project(':ReactAndroid').projectDir
+ def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
+ dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
+ from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
+ into("$buildDir/react-ndk/exported")
+ }
+ def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
+ dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
+ from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
+ into("$buildDir/react-ndk/exported")
+ }
+ afterEvaluate {
+ // If you wish to add a custom TurboModule or component locally,
+ // you should uncomment this line.
+ // preBuild.dependsOn("generateCodegenArtifactsFromSchema")
+ preDebugBuild.dependsOn(packageReactNdkDebugLibs)
+ preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
+
+ // Due to a bug inside AGP, we have to explicitly set a dependency
+ // between configureNdkBuild* tasks and the preBuild tasks.
+ // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
+ configureNdkBuildRelease.dependsOn(preReleaseBuild)
+ configureNdkBuildDebug.dependsOn(preDebugBuild)
+ reactNativeArchitectures().each { architecture ->
+ tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
+ dependsOn("preDebugBuild")
+ }
+ tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
+ dependsOn("preReleaseBuild")
+ }
+ }
+ }
}
+
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
- include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
+ include (*reactNativeArchitectures())
}
}
signingConfigs {
@@ -156,11 +222,6 @@ android {
buildTypes {
debug {
signingConfig signingConfigs.debug
- if (nativeArchitectures) {
- ndk {
- abiFilters nativeArchitectures.split(',')
- }
- }
}
release {
// Caution! In production, you need to generate your own keystore file.
@@ -190,6 +251,7 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
+
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
@@ -217,6 +279,18 @@ dependencies {
}
}
+if (isNewArchitectureEnabled()) {
+ // If new architecture is enabled, we let you build RN from source
+ // Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
+ // This will be applied to all the imported transtitive dependency.
+ configurations.all {
+ resolutionStrategy.dependencySubstitution {
+ substitute(module("com.facebook.react:react-native"))
+ .using(project(":ReactAndroid")).because("On New Architecture we're building React Native from source")
+ }
+ }
+}
+
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
@@ -225,3 +299,11 @@ task copyDownloadableDepsToLibs(type: Copy) {
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
+
+def isNewArchitectureEnabled() {
+ // To opt-in for the New Architecture, you can either:
+ // - Set `newArchEnabled` to true inside the `gradle.properties` file
+ // - Invoke gradle with `-newArchEnabled=true`
+ // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
+ return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
+}
diff --git a/template/android/app/src/debug/AndroidManifest.xml b/template/android/app/src/debug/AndroidManifest.xml
index b2f3ad9f..4b185bc1 100644
--- a/template/android/app/src/debug/AndroidManifest.xml
+++ b/template/android/app/src/debug/AndroidManifest.xml
@@ -8,6 +8,6 @@
android:usesCleartextTraffic="true"
tools:targetApi="28"
tools:ignore="GoogleAppIndexingWarning">
-
+
diff --git a/template/android/app/src/debug/java/com/helloworld/ReactNativeFlipper.java b/template/android/app/src/debug/java/com/helloworld/ReactNativeFlipper.java
index 8b7f0913..8ed784fe 100644
--- a/template/android/app/src/debug/java/com/helloworld/ReactNativeFlipper.java
+++ b/template/android/app/src/debug/java/com/helloworld/ReactNativeFlipper.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) Facebook, Inc. and its affiliates.
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
*
*
This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
@@ -19,6 +19,7 @@
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
+import com.facebook.react.ReactInstanceEventListener;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
@@ -51,7 +52,7 @@ public void apply(OkHttpClient.Builder builder) {
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if (reactContext == null) {
reactInstanceManager.addReactInstanceEventListener(
- new ReactInstanceManager.ReactInstanceEventListener() {
+ new ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext reactContext) {
reactInstanceManager.removeReactInstanceEventListener(this);
diff --git a/template/android/app/src/main/AndroidManifest.xml b/template/android/app/src/main/AndroidManifest.xml
index 6db8bad3..7ba57ca1 100644
--- a/template/android/app/src/main/AndroidManifest.xml
+++ b/template/android/app/src/main/AndroidManifest.xml
@@ -13,9 +13,10 @@
+ android:windowSoftInputMode="adjustResize"
+ android:exported="true">
diff --git a/template/android/app/src/main/java/com/helloworld/MainActivity.java b/template/android/app/src/main/java/com/helloworld/MainActivity.java
index c7106d57..24f41285 100644
--- a/template/android/app/src/main/java/com/helloworld/MainActivity.java
+++ b/template/android/app/src/main/java/com/helloworld/MainActivity.java
@@ -1,6 +1,8 @@
package com.helloworld;
import com.facebook.react.ReactActivity;
+import com.facebook.react.ReactActivityDelegate;
+import com.facebook.react.ReactRootView;
public class MainActivity extends ReactActivity {
@@ -12,4 +14,27 @@ public class MainActivity extends ReactActivity {
protected String getMainComponentName() {
return "HelloWorld";
}
+
+ /**
+ * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
+ * you can specify the rendered you wish to use (Fabric or the older renderer).
+ */
+ @Override
+ protected ReactActivityDelegate createReactActivityDelegate() {
+ return new MainActivityDelegate(this, getMainComponentName());
+ }
+
+ public static class MainActivityDelegate extends ReactActivityDelegate {
+ public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
+ super(activity, mainComponentName);
+ }
+
+ @Override
+ protected ReactRootView createRootView() {
+ ReactRootView reactRootView = new ReactRootView(getContext());
+ // If you opted-in for the New Architecture, we enable the Fabric Renderer.
+ reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
+ return reactRootView;
+ }
+ }
}
diff --git a/template/android/app/src/main/java/com/helloworld/MainApplication.java b/template/android/app/src/main/java/com/helloworld/MainApplication.java
index e55c37b9..eedd1929 100644
--- a/template/android/app/src/main/java/com/helloworld/MainApplication.java
+++ b/template/android/app/src/main/java/com/helloworld/MainApplication.java
@@ -7,7 +7,9 @@
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
+import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.soloader.SoLoader;
+import com.helloworld.newarchitecture.MainApplicationReactNativeHost;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
@@ -35,14 +37,23 @@ protected String getJSMainModuleName() {
}
};
+ private final ReactNativeHost mNewArchitectureNativeHost =
+ new MainApplicationReactNativeHost(this);
+
@Override
public ReactNativeHost getReactNativeHost() {
- return mReactNativeHost;
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+ return mNewArchitectureNativeHost;
+ } else {
+ return mReactNativeHost;
+ }
}
@Override
public void onCreate() {
super.onCreate();
+ // If you opted-in for the New Architecture, we enable the TurboModule system
+ ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
diff --git a/template/android/app/src/main/java/com/helloworld/newarchitecture/MainApplicationReactNativeHost.java b/template/android/app/src/main/java/com/helloworld/newarchitecture/MainApplicationReactNativeHost.java
new file mode 100644
index 00000000..f555e364
--- /dev/null
+++ b/template/android/app/src/main/java/com/helloworld/newarchitecture/MainApplicationReactNativeHost.java
@@ -0,0 +1,116 @@
+package com.helloworld.newarchitecture;
+
+import android.app.Application;
+import androidx.annotation.NonNull;
+import com.facebook.react.PackageList;
+import com.facebook.react.ReactInstanceManager;
+import com.facebook.react.ReactNativeHost;
+import com.facebook.react.ReactPackage;
+import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
+import com.facebook.react.bridge.JSIModulePackage;
+import com.facebook.react.bridge.JSIModuleProvider;
+import com.facebook.react.bridge.JSIModuleSpec;
+import com.facebook.react.bridge.JSIModuleType;
+import com.facebook.react.bridge.JavaScriptContextHolder;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.UIManager;
+import com.facebook.react.fabric.ComponentFactory;
+import com.facebook.react.fabric.CoreComponentsRegistry;
+import com.facebook.react.fabric.EmptyReactNativeConfig;
+import com.facebook.react.fabric.FabricJSIModuleProvider;
+import com.facebook.react.uimanager.ViewManagerRegistry;
+import com.helloworld.BuildConfig;
+import com.helloworld.newarchitecture.components.MainComponentsRegistry;
+import com.helloworld.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
+ * TurboModule delegates and the Fabric Renderer.
+ *
+ * Please note that this class is used ONLY if you opt-in for the New Architecture (see the
+ * `newArchEnabled` property). Is ignored otherwise.
+ */
+public class MainApplicationReactNativeHost extends ReactNativeHost {
+ public MainApplicationReactNativeHost(Application application) {
+ super(application);
+ }
+
+ @Override
+ public boolean getUseDeveloperSupport() {
+ return BuildConfig.DEBUG;
+ }
+
+ @Override
+ protected List getPackages() {
+ List packages = new PackageList(this).getPackages();
+ // Packages that cannot be autolinked yet can be added manually here, for example:
+ // packages.add(new MyReactNativePackage());
+ // TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
+ // packages.add(new TurboReactPackage() { ... });
+ // If you have custom Fabric Components, their ViewManagers should also be loaded here
+ // inside a ReactPackage.
+ return packages;
+ }
+
+ @Override
+ protected String getJSMainModuleName() {
+ return "index";
+ }
+
+ @NonNull
+ @Override
+ protected ReactPackageTurboModuleManagerDelegate.Builder
+ getReactPackageTurboModuleManagerDelegateBuilder() {
+ // Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
+ // for the new architecture and to use TurboModules correctly.
+ return new MainApplicationTurboModuleManagerDelegate.Builder();
+ }
+
+ @Override
+ protected JSIModulePackage getJSIModulePackage() {
+ return new JSIModulePackage() {
+ @Override
+ public List getJSIModules(
+ final ReactApplicationContext reactApplicationContext,
+ final JavaScriptContextHolder jsContext) {
+ final List specs = new ArrayList<>();
+
+ // Here we provide a new JSIModuleSpec that will be responsible of providing the
+ // custom Fabric Components.
+ specs.add(
+ new JSIModuleSpec() {
+ @Override
+ public JSIModuleType getJSIModuleType() {
+ return JSIModuleType.UIManager;
+ }
+
+ @Override
+ public JSIModuleProvider getJSIModuleProvider() {
+ final ComponentFactory componentFactory = new ComponentFactory();
+ CoreComponentsRegistry.register(componentFactory);
+
+ // Here we register a Components Registry.
+ // The one that is generated with the template contains no components
+ // and just provides you the one from React Native core.
+ MainComponentsRegistry.register(componentFactory);
+
+ final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
+
+ ViewManagerRegistry viewManagerRegistry =
+ new ViewManagerRegistry(
+ reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
+
+ return new FabricJSIModuleProvider(
+ reactApplicationContext,
+ componentFactory,
+ new EmptyReactNativeConfig(),
+ viewManagerRegistry);
+ }
+ });
+ return specs;
+ }
+ };
+ }
+}
diff --git a/template/android/app/src/main/java/com/helloworld/newarchitecture/components/MainComponentsRegistry.java b/template/android/app/src/main/java/com/helloworld/newarchitecture/components/MainComponentsRegistry.java
new file mode 100644
index 00000000..c74d0cca
--- /dev/null
+++ b/template/android/app/src/main/java/com/helloworld/newarchitecture/components/MainComponentsRegistry.java
@@ -0,0 +1,36 @@
+package com.helloworld.newarchitecture.components;
+
+import com.facebook.jni.HybridData;
+import com.facebook.proguard.annotations.DoNotStrip;
+import com.facebook.react.fabric.ComponentFactory;
+import com.facebook.soloader.SoLoader;
+
+/**
+ * Class responsible to load the custom Fabric Components. This class has native methods and needs a
+ * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
+ * folder for you).
+ *
+ * Please note that this class is used ONLY if you opt-in for the New Architecture (see the
+ * `newArchEnabled` property). Is ignored otherwise.
+ */
+@DoNotStrip
+public class MainComponentsRegistry {
+ static {
+ SoLoader.loadLibrary("fabricjni");
+ }
+
+ @DoNotStrip private final HybridData mHybridData;
+
+ @DoNotStrip
+ private native HybridData initHybrid(ComponentFactory componentFactory);
+
+ @DoNotStrip
+ private MainComponentsRegistry(ComponentFactory componentFactory) {
+ mHybridData = initHybrid(componentFactory);
+ }
+
+ @DoNotStrip
+ public static MainComponentsRegistry register(ComponentFactory componentFactory) {
+ return new MainComponentsRegistry(componentFactory);
+ }
+}
diff --git a/template/android/app/src/main/java/com/helloworld/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java b/template/android/app/src/main/java/com/helloworld/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
new file mode 100644
index 00000000..8593b3bb
--- /dev/null
+++ b/template/android/app/src/main/java/com/helloworld/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
@@ -0,0 +1,48 @@
+package com.helloworld.newarchitecture.modules;
+
+import com.facebook.jni.HybridData;
+import com.facebook.react.ReactPackage;
+import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.soloader.SoLoader;
+import java.util.List;
+
+/**
+ * Class responsible to load the TurboModules. This class has native methods and needs a
+ * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
+ * folder for you).
+ *
+ *
Please note that this class is used ONLY if you opt-in for the New Architecture (see the
+ * `newArchEnabled` property). Is ignored otherwise.
+ */
+public class MainApplicationTurboModuleManagerDelegate
+ extends ReactPackageTurboModuleManagerDelegate {
+
+ private static volatile boolean sIsSoLibraryLoaded;
+
+ protected MainApplicationTurboModuleManagerDelegate(
+ ReactApplicationContext reactApplicationContext, List packages) {
+ super(reactApplicationContext, packages);
+ }
+
+ protected native HybridData initHybrid();
+
+ native boolean canCreateTurboModule(String moduleName);
+
+ public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
+ protected MainApplicationTurboModuleManagerDelegate build(
+ ReactApplicationContext context, List packages) {
+ return new MainApplicationTurboModuleManagerDelegate(context, packages);
+ }
+ }
+
+ @Override
+ protected synchronized void maybeLoadOtherSoLibraries() {
+ if (!sIsSoLibraryLoaded) {
+ // If you change the name of your application .so file in the Android.mk file,
+ // make sure you update the name here as well.
+ SoLoader.loadLibrary("helloworld_appmodules");
+ sIsSoLibraryLoaded = true;
+ }
+ }
+}
diff --git a/template/android/app/src/main/jni/Android.mk b/template/android/app/src/main/jni/Android.mk
new file mode 100644
index 00000000..0ae63667
--- /dev/null
+++ b/template/android/app/src/main/jni/Android.mk
@@ -0,0 +1,49 @@
+THIS_DIR := $(call my-dir)
+
+include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
+
+# If you wish to add a custom TurboModule or Fabric component in your app you
+# will have to include the following autogenerated makefile.
+# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
+include $(CLEAR_VARS)
+
+LOCAL_PATH := $(THIS_DIR)
+
+# You can customize the name of your application .so file here.
+LOCAL_MODULE := helloworld_appmodules
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)
+LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
+LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
+
+# If you wish to add a custom TurboModule or Fabric component in your app you
+# will have to uncomment those lines to include the generated source
+# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
+#
+# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
+# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
+# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
+
+# Here you should add any native library you wish to depend on.
+LOCAL_SHARED_LIBRARIES := \
+ libfabricjni \
+ libfbjni \
+ libfolly_futures \
+ libfolly_json \
+ libglog \
+ libjsi \
+ libreact_codegen_rncore \
+ libreact_debug \
+ libreact_nativemodule_core \
+ libreact_render_componentregistry \
+ libreact_render_core \
+ libreact_render_debug \
+ libreact_render_graphics \
+ librrc_view \
+ libruntimeexecutor \
+ libturbomodulejsijni \
+ libyoga
+
+LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/template/android/app/src/main/jni/MainApplicationModuleProvider.cpp b/template/android/app/src/main/jni/MainApplicationModuleProvider.cpp
new file mode 100644
index 00000000..0ac23cc6
--- /dev/null
+++ b/template/android/app/src/main/jni/MainApplicationModuleProvider.cpp
@@ -0,0 +1,24 @@
+#include "MainApplicationModuleProvider.h"
+
+#include
+
+namespace facebook {
+namespace react {
+
+std::shared_ptr MainApplicationModuleProvider(
+ const std::string moduleName,
+ const JavaTurboModule::InitParams ¶ms) {
+ // Here you can provide your own module provider for TurboModules coming from
+ // either your application or from external libraries. The approach to follow
+ // is similar to the following (for a library called `samplelibrary`:
+ //
+ // auto module = samplelibrary_ModuleProvider(moduleName, params);
+ // if (module != nullptr) {
+ // return module;
+ // }
+ // return rncore_ModuleProvider(moduleName, params);
+ return rncore_ModuleProvider(moduleName, params);
+}
+
+} // namespace react
+} // namespace facebook
diff --git a/template/android/app/src/main/jni/MainApplicationModuleProvider.h b/template/android/app/src/main/jni/MainApplicationModuleProvider.h
new file mode 100644
index 00000000..0fa43fa6
--- /dev/null
+++ b/template/android/app/src/main/jni/MainApplicationModuleProvider.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include
+#include
+
+#include
+
+namespace facebook {
+namespace react {
+
+std::shared_ptr MainApplicationModuleProvider(
+ const std::string moduleName,
+ const JavaTurboModule::InitParams ¶ms);
+
+} // namespace react
+} // namespace facebook
diff --git a/template/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp b/template/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
new file mode 100644
index 00000000..dbbdc3d1
--- /dev/null
+++ b/template/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
@@ -0,0 +1,45 @@
+#include "MainApplicationTurboModuleManagerDelegate.h"
+#include "MainApplicationModuleProvider.h"
+
+namespace facebook {
+namespace react {
+
+jni::local_ref
+MainApplicationTurboModuleManagerDelegate::initHybrid(
+ jni::alias_ref) {
+ return makeCxxInstance();
+}
+
+void MainApplicationTurboModuleManagerDelegate::registerNatives() {
+ registerHybrid({
+ makeNativeMethod(
+ "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
+ makeNativeMethod(
+ "canCreateTurboModule",
+ MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
+ });
+}
+
+std::shared_ptr
+MainApplicationTurboModuleManagerDelegate::getTurboModule(
+ const std::string name,
+ const std::shared_ptr jsInvoker) {
+ // Not implemented yet: provide pure-C++ NativeModules here.
+ return nullptr;
+}
+
+std::shared_ptr
+MainApplicationTurboModuleManagerDelegate::getTurboModule(
+ const std::string name,
+ const JavaTurboModule::InitParams ¶ms) {
+ return MainApplicationModuleProvider(name, params);
+}
+
+bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
+ std::string name) {
+ return getTurboModule(name, nullptr) != nullptr ||
+ getTurboModule(name, {.moduleName = name}) != nullptr;
+}
+
+} // namespace react
+} // namespace facebook
diff --git a/template/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h b/template/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
new file mode 100644
index 00000000..25f27722
--- /dev/null
+++ b/template/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
@@ -0,0 +1,38 @@
+#include
+#include
+
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+class MainApplicationTurboModuleManagerDelegate
+ : public jni::HybridClass<
+ MainApplicationTurboModuleManagerDelegate,
+ TurboModuleManagerDelegate> {
+ public:
+ // Adapt it to the package you used for your Java class.
+ static constexpr auto kJavaDescriptor =
+ "Lcom/helloworld/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
+
+ static jni::local_ref initHybrid(jni::alias_ref);
+
+ static void registerNatives();
+
+ std::shared_ptr getTurboModule(
+ const std::string name,
+ const std::shared_ptr jsInvoker) override;
+ std::shared_ptr getTurboModule(
+ const std::string name,
+ const JavaTurboModule::InitParams ¶ms) override;
+
+ /**
+ * Test-only method. Allows user to verify whether a TurboModule can be
+ * created by instances of this class.
+ */
+ bool canCreateTurboModule(std::string name);
+};
+
+} // namespace react
+} // namespace facebook
diff --git a/template/android/app/src/main/jni/MainComponentsRegistry.cpp b/template/android/app/src/main/jni/MainComponentsRegistry.cpp
new file mode 100644
index 00000000..8f7edffd
--- /dev/null
+++ b/template/android/app/src/main/jni/MainComponentsRegistry.cpp
@@ -0,0 +1,61 @@
+#include "MainComponentsRegistry.h"
+
+#include
+#include
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
+
+std::shared_ptr
+MainComponentsRegistry::sharedProviderRegistry() {
+ auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
+
+ // Custom Fabric Components go here. You can register custom
+ // components coming from your App or from 3rd party libraries here.
+ //
+ // providerRegistry->add(concreteComponentDescriptorProvider<
+ // AocViewerComponentDescriptor>());
+ return providerRegistry;
+}
+
+jni::local_ref
+MainComponentsRegistry::initHybrid(
+ jni::alias_ref,
+ ComponentFactory *delegate) {
+ auto instance = makeCxxInstance(delegate);
+
+ auto buildRegistryFunction =
+ [](EventDispatcher::Weak const &eventDispatcher,
+ ContextContainer::Shared const &contextContainer)
+ -> ComponentDescriptorRegistry::Shared {
+ auto registry = MainComponentsRegistry::sharedProviderRegistry()
+ ->createComponentDescriptorRegistry(
+ {eventDispatcher, contextContainer});
+
+ auto mutableRegistry =
+ std::const_pointer_cast(registry);
+
+ mutableRegistry->setFallbackComponentDescriptor(
+ std::make_shared(
+ ComponentDescriptorParameters{
+ eventDispatcher, contextContainer, nullptr}));
+
+ return registry;
+ };
+
+ delegate->buildRegistryFunction = buildRegistryFunction;
+ return instance;
+}
+
+void MainComponentsRegistry::registerNatives() {
+ registerHybrid({
+ makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
+ });
+}
+
+} // namespace react
+} // namespace facebook
diff --git a/template/android/app/src/main/jni/MainComponentsRegistry.h b/template/android/app/src/main/jni/MainComponentsRegistry.h
new file mode 100644
index 00000000..d61cbffa
--- /dev/null
+++ b/template/android/app/src/main/jni/MainComponentsRegistry.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+class MainComponentsRegistry
+ : public facebook::jni::HybridClass {
+ public:
+ // Adapt it to the package you used for your Java class.
+ constexpr static auto kJavaDescriptor =
+ "Lcom/helloworld/newarchitecture/components/MainComponentsRegistry;";
+
+ static void registerNatives();
+
+ MainComponentsRegistry(ComponentFactory *delegate);
+
+ private:
+ static std::shared_ptr
+ sharedProviderRegistry();
+
+ static jni::local_ref initHybrid(
+ jni::alias_ref,
+ ComponentFactory *delegate);
+};
+
+} // namespace react
+} // namespace facebook
diff --git a/template/android/app/src/main/jni/OnLoad.cpp b/template/android/app/src/main/jni/OnLoad.cpp
new file mode 100644
index 00000000..c569b6e8
--- /dev/null
+++ b/template/android/app/src/main/jni/OnLoad.cpp
@@ -0,0 +1,11 @@
+#include
+#include "MainApplicationTurboModuleManagerDelegate.h"
+#include "MainComponentsRegistry.h"
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
+ return facebook::jni::initialize(vm, [] {
+ facebook::react::MainApplicationTurboModuleManagerDelegate::
+ registerNatives();
+ facebook::react::MainComponentsRegistry::registerNatives();
+ });
+}
diff --git a/template/android/app/src/main/res/drawable/rn_edit_text_material.xml b/template/android/app/src/main/res/drawable/rn_edit_text_material.xml
index bb6f578c..f35d9962 100644
--- a/template/android/app/src/main/res/drawable/rn_edit_text_material.xml
+++ b/template/android/app/src/main/res/drawable/rn_edit_text_material.xml
@@ -1,9 +1,12 @@
-
\ No newline at end of file
+
+
diff --git a/template/android/build.gradle b/template/android/build.gradle
index 3be1031f..8a1d68f9 100644
--- a/template/android/build.gradle
+++ b/template/android/build.gradle
@@ -2,10 +2,10 @@
buildscript {
ext {
- buildToolsVersion = "30.0.2"
+ buildToolsVersion = "31.0.0"
minSdkVersion = 21
- compileSdkVersion = 30
- targetSdkVersion = 30
+ compileSdkVersion = 31
+ targetSdkVersion = 31
ndkVersion = "21.4.7075529"
}
repositories {
@@ -13,7 +13,9 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath("com.android.tools.build:gradle:4.2.2")
+ classpath("com.android.tools.build:gradle:7.0.4")
+ classpath("com.facebook.react:react-native-gradle-plugin")
+ classpath("de.undercouch:gradle-download-task:4.1.2")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
diff --git a/template/android/gradle.properties b/template/android/gradle.properties
index 11d6e024..fa4feae5 100644
--- a/template/android/gradle.properties
+++ b/template/android/gradle.properties
@@ -9,8 +9,8 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx1024m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
+org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
@@ -25,4 +25,16 @@ android.useAndroidX=true
android.enableJetifier=true
# Version of flipper SDK to use with React Native
-FLIPPER_VERSION=0.99.0
+FLIPPER_VERSION=0.125.0
+
+# Use this property to specify which architecture you want to build.
+# You can also override it from the CLI using
+# ./gradlew -PreactNativeArchitectures=x86_64
+reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
+
+# Use this property to enable support to the new architecture.
+# This will allow you to use TurboModules and the Fabric render in
+# your application. You should enable this flag either if you want
+# to write custom TurboModules/Fabric components OR use libraries that
+# are providing them.
+newArchEnabled=false
diff --git a/template/android/gradle/wrapper/gradle-wrapper.jar b/template/android/gradle/wrapper/gradle-wrapper.jar
index e708b1c0..7454180f 100644
Binary files a/template/android/gradle/wrapper/gradle-wrapper.jar and b/template/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/template/android/gradle/wrapper/gradle-wrapper.properties b/template/android/gradle/wrapper/gradle-wrapper.properties
index a0f7639f..669386b8 100644
--- a/template/android/gradle/wrapper/gradle-wrapper.properties
+++ b/template/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/template/android/gradlew b/template/android/gradlew
index 4f906e0c..1b6c7873 100755
--- a/template/android/gradlew
+++ b/template/android/gradlew
@@ -1,7 +1,7 @@
-#!/usr/bin/env sh
+#!/bin/sh
#
-# Copyright 2015 the original author or authors.
+# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,67 +17,101 @@
#
##############################################################################
-##
-## Gradle start up script for UN*X
-##
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
##############################################################################
# Attempt to set APP_HOME
+
# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
+APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
warn () {
echo "$*"
-}
+} >&2
die () {
echo
echo "$*"
echo
exit 1
-}
+} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACMD=$JAVA_HOME/jre/sh/java
else
- JAVACMD="$JAVA_HOME/bin/java"
+ JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
- JAVACMD="java"
+ JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@@ -106,80 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
fi
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
# Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
fi
- i=`expr $i + 1`
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
fi
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
exec "$JAVACMD" "$@"
diff --git a/template/android/settings.gradle b/template/android/settings.gradle
index e50c29d6..2f93b711 100644
--- a/template/android/settings.gradle
+++ b/template/android/settings.gradle
@@ -1,3 +1,9 @@
rootProject.name = 'HelloWorld'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
+includeBuild('../node_modules/react-native-gradle-plugin')
+
+if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
+ include(":ReactAndroid")
+ project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
+}
diff --git a/template/ios/HelloWorld.xcodeproj/project.pbxproj b/template/ios/HelloWorld.xcodeproj/project.pbxproj
index abf48663..7dfdffdd 100644
--- a/template/ios/HelloWorld.xcodeproj/project.pbxproj
+++ b/template/ios/HelloWorld.xcodeproj/project.pbxproj
@@ -8,11 +8,11 @@
/* Begin PBXBuildFile section */
00E356F31AD99517003FC87E /* HelloWorldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* HelloWorldTests.m */; };
- 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
+ 0C80B921A6F3F58F76C31292 /* libPods-HelloWorld.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-HelloWorld.a */; };
+ 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
- 6172F2D35A4C3AA820D92908 /* libPods-HelloWorld.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6423831EA8574132BED9D8CC /* libPods-HelloWorld.a */; };
- 7EF68E3733C33B6898317E18 /* libPods-HelloWorld-HelloWorldTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ABFE59519B596E51CEFDCCC0 /* libPods-HelloWorld-HelloWorldTests.a */; };
+ 7699B88040F8A987B510C191 /* libPods-HelloWorld-HelloWorldTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-HelloWorld-HelloWorldTests.a */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
@@ -32,17 +32,17 @@
00E356F21AD99517003FC87E /* HelloWorldTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HelloWorldTests.m; sourceTree = ""; };
13B07F961A680F5B00A75B9A /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = HelloWorld/AppDelegate.h; sourceTree = ""; };
- 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = HelloWorld/AppDelegate.m; sourceTree = ""; };
+ 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = HelloWorld/AppDelegate.mm; sourceTree = ""; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = HelloWorld/Images.xcassets; sourceTree = ""; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = HelloWorld/Info.plist; sourceTree = ""; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = HelloWorld/main.m; sourceTree = ""; };
- 1D0AE47A65C8663E3B452821 /* Pods-HelloWorld-HelloWorldTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld-HelloWorldTests.release.xcconfig"; path = "Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests.release.xcconfig"; sourceTree = ""; };
- 6423831EA8574132BED9D8CC /* libPods-HelloWorld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld.a"; sourceTree = BUILT_PRODUCTS_DIR; };
- 6C97AB639B58BBB4B15BBE30 /* Pods-HelloWorld-HelloWorldTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld-HelloWorldTests.debug.xcconfig"; path = "Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests.debug.xcconfig"; sourceTree = ""; };
+ 19F6CBCC0A4E27FBF8BF4A61 /* libPods-HelloWorld-HelloWorldTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld-HelloWorldTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 3B4392A12AC88292D35C810B /* Pods-HelloWorld.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.debug.xcconfig"; path = "Target Support Files/Pods-HelloWorld/Pods-HelloWorld.debug.xcconfig"; sourceTree = ""; };
+ 5709B34CF0A7D63546082F79 /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = ""; };
+ 5B7EB9410499542E8C5724F5 /* Pods-HelloWorld-HelloWorldTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld-HelloWorldTests.debug.xcconfig"; path = "Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests.debug.xcconfig"; sourceTree = ""; };
+ 5DCACB8F33CDC322A6C60F78 /* libPods-HelloWorld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld.a"; sourceTree = BUILT_PRODUCTS_DIR; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = HelloWorld/LaunchScreen.storyboard; sourceTree = ""; };
- ABFE59519B596E51CEFDCCC0 /* libPods-HelloWorld-HelloWorldTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld-HelloWorldTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
- C0A881CF5CF3F2B244570E2A /* Pods-HelloWorld.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.debug.xcconfig"; path = "Target Support Files/Pods-HelloWorld/Pods-HelloWorld.debug.xcconfig"; sourceTree = ""; };
- D00AAFFCFCFDA5787532823F /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = ""; };
+ 89C6BE57DB24E9ADA2F236DE /* Pods-HelloWorld-HelloWorldTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld-HelloWorldTests.release.xcconfig"; path = "Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests.release.xcconfig"; sourceTree = ""; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
@@ -51,7 +51,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 7EF68E3733C33B6898317E18 /* libPods-HelloWorld-HelloWorldTests.a in Frameworks */,
+ 7699B88040F8A987B510C191 /* libPods-HelloWorld-HelloWorldTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -59,7 +59,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 6172F2D35A4C3AA820D92908 /* libPods-HelloWorld.a in Frameworks */,
+ 0C80B921A6F3F58F76C31292 /* libPods-HelloWorld.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -87,7 +87,7 @@
isa = PBXGroup;
children = (
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
- 13B07FB01A68108700A75B9A /* AppDelegate.m */,
+ 13B07FB01A68108700A75B9A /* AppDelegate.mm */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */,
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
@@ -100,8 +100,8 @@
isa = PBXGroup;
children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
- 6423831EA8574132BED9D8CC /* libPods-HelloWorld.a */,
- ABFE59519B596E51CEFDCCC0 /* libPods-HelloWorld-HelloWorldTests.a */,
+ 5DCACB8F33CDC322A6C60F78 /* libPods-HelloWorld.a */,
+ 19F6CBCC0A4E27FBF8BF4A61 /* libPods-HelloWorld-HelloWorldTests.a */,
);
name = Frameworks;
sourceTree = "";
@@ -121,7 +121,7 @@
00E356EF1AD99517003FC87E /* HelloWorldTests */,
83CBBA001A601CBA00E9B192 /* Products */,
2D16E6871FA4F8E400B85C8A /* Frameworks */,
- E233CBF5F47BEE60B243DCF8 /* Pods */,
+ BBD78D7AC51CEA395F1C20DB /* Pods */,
);
indentWidth = 2;
sourceTree = "";
@@ -137,15 +137,14 @@
name = Products;
sourceTree = "";
};
- E233CBF5F47BEE60B243DCF8 /* Pods */ = {
+ BBD78D7AC51CEA395F1C20DB /* Pods */ = {
isa = PBXGroup;
children = (
- C0A881CF5CF3F2B244570E2A /* Pods-HelloWorld.debug.xcconfig */,
- D00AAFFCFCFDA5787532823F /* Pods-HelloWorld.release.xcconfig */,
- 6C97AB639B58BBB4B15BBE30 /* Pods-HelloWorld-HelloWorldTests.debug.xcconfig */,
- 1D0AE47A65C8663E3B452821 /* Pods-HelloWorld-HelloWorldTests.release.xcconfig */,
+ 3B4392A12AC88292D35C810B /* Pods-HelloWorld.debug.xcconfig */,
+ 5709B34CF0A7D63546082F79 /* Pods-HelloWorld.release.xcconfig */,
+ 5B7EB9410499542E8C5724F5 /* Pods-HelloWorld-HelloWorldTests.debug.xcconfig */,
+ 89C6BE57DB24E9ADA2F236DE /* Pods-HelloWorld-HelloWorldTests.release.xcconfig */,
);
- name = Pods;
path = Pods;
sourceTree = "";
};
@@ -156,12 +155,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "HelloWorldTests" */;
buildPhases = (
- A130D646172E58E1D159D8F2 /* [CP] Check Pods Manifest.lock */,
+ A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */,
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
- 077E01280D4B4AD18B2E1770 /* [CP] Embed Pods Frameworks */,
- 4E62BDF20514810D028A5FBF /* [CP] Copy Pods Resources */,
+ C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */,
+ F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -177,14 +176,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "HelloWorld" */;
buildPhases = (
- 3E482C27206C4DEF2FE45063 /* [CP] Check Pods Manifest.lock */,
+ C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
FD10A7F022414F080027D42C /* Start Packager */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
- C8AC78B0264D0F9F6F6D630E /* [CP] Embed Pods Frameworks */,
- ADC9DDC32298B72B3CF5DC8E /* [CP] Copy Pods Resources */,
+ 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */,
+ E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -265,24 +264,24 @@
shellPath = /bin/sh;
shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
};
- 077E01280D4B4AD18B2E1770 /* [CP] Embed Pods Frameworks */ = {
+ 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
- 3E482C27206C4DEF2FE45063 /* [CP] Check Pods Manifest.lock */ = {
+ A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -297,53 +296,53 @@
outputFileListPaths = (
);
outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-HelloWorld-checkManifestLockResult.txt",
+ "$(DERIVED_FILE_DIR)/Pods-HelloWorld-HelloWorldTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- 4E62BDF20514810D028A5FBF /* [CP] Copy Pods Resources */ = {
+ C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-resources-${CONFIGURATION}-input-files.xcfilelist",
);
- name = "[CP] Copy Pods Resources";
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-resources-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-HelloWorld-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-resources.sh\"\n";
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
- A130D646172E58E1D159D8F2 /* [CP] Check Pods Manifest.lock */ = {
+ C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
+ name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
- );
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-HelloWorld-HelloWorldTests-checkManifestLockResult.txt",
+ "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
- ADC9DDC32298B72B3CF5DC8E /* [CP] Copy Pods Resources */ = {
+ E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -360,21 +359,21 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- C8AC78B0264D0F9F6F6D630E /* [CP] Embed Pods Frameworks */ = {
+ F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-resources-${CONFIGURATION}-input-files.xcfilelist",
);
- name = "[CP] Embed Pods Frameworks";
+ name = "[CP] Copy Pods Resources";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ "${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-frameworks.sh\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
FD10A7F022414F080027D42C /* Start Packager */ = {
@@ -411,7 +410,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
+ 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -429,7 +428,7 @@
/* Begin XCBuildConfiguration section */
00E356F61AD99517003FC87E /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 6C97AB639B58BBB4B15BBE30 /* Pods-HelloWorld-HelloWorldTests.debug.xcconfig */;
+ baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-HelloWorld-HelloWorldTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
GCC_PREPROCESSOR_DEFINITIONS = (
@@ -456,7 +455,7 @@
};
00E356F71AD99517003FC87E /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 1D0AE47A65C8663E3B452821 /* Pods-HelloWorld-HelloWorldTests.release.xcconfig */;
+ baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-HelloWorld-HelloWorldTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
COPY_PHASE_STRIP = NO;
@@ -480,7 +479,7 @@
};
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = C0A881CF5CF3F2B244570E2A /* Pods-HelloWorld.debug.xcconfig */;
+ baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-HelloWorld.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@@ -506,7 +505,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = D00AAFFCFCFDA5787532823F /* Pods-HelloWorld.release.xcconfig */;
+ baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-HelloWorld.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@@ -533,7 +532,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
@@ -589,6 +588,12 @@
);
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
+ OTHER_CPLUSPLUSFLAGS = (
+ "$(OTHER_CFLAGS)",
+ "-DFOLLY_NO_CONFIG",
+ "-DFOLLY_MOBILE=1",
+ "-DFOLLY_USE_LIBCPP=1",
+ );
SDKROOT = iphoneos;
};
name = Debug;
@@ -598,7 +603,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
@@ -646,6 +651,12 @@
"\"$(inherited)\"",
);
MTL_ENABLE_DEBUG_INFO = NO;
+ OTHER_CPLUSPLUSFLAGS = (
+ "$(OTHER_CFLAGS)",
+ "-DFOLLY_NO_CONFIG",
+ "-DFOLLY_MOBILE=1",
+ "-DFOLLY_USE_LIBCPP=1",
+ );
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
diff --git a/template/ios/HelloWorld/AppDelegate.m b/template/ios/HelloWorld/AppDelegate.m
deleted file mode 100644
index 59b62377..00000000
--- a/template/ios/HelloWorld/AppDelegate.m
+++ /dev/null
@@ -1,62 +0,0 @@
-#import "AppDelegate.h"
-
-#import
-#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
-
-@implementation AppDelegate
-
-- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
-{
-#ifdef FB_SONARKIT_ENABLED
- InitializeFlipper(application);
-#endif
-
- RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
- RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
- moduleName:@"HelloWorld"
- initialProperties:nil];
-
- if (@available(iOS 13.0, *)) {
- rootView.backgroundColor = [UIColor systemBackgroundColor];
- } else {
- rootView.backgroundColor = [UIColor whiteColor];
- }
-
- self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
- UIViewController *rootViewController = [UIViewController new];
- rootViewController.view = rootView;
- self.window.rootViewController = rootViewController;
- [self.window makeKeyAndVisible];
- 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
diff --git a/template/ios/HelloWorld/AppDelegate.mm b/template/ios/HelloWorld/AppDelegate.mm
new file mode 100644
index 00000000..cef8d202
--- /dev/null
+++ b/template/ios/HelloWorld/AppDelegate.mm
@@ -0,0 +1,108 @@
+#import "AppDelegate.h"
+
+#import
+#import
+#import
+
+#import
+
+#if RCT_NEW_ARCH_ENABLED
+#import
+#import
+#import
+#import
+#import
+#import
+
+#import
+
+@interface AppDelegate () {
+ RCTTurboModuleManager *_turboModuleManager;
+ RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
+ std::shared_ptr _reactNativeConfig;
+ facebook::react::ContextContainer::Shared _contextContainer;
+}
+@end
+#endif
+
+@implementation AppDelegate
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ RCTAppSetupPrepareApp(application);
+
+ RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
+
+#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
+
+ UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"HelloWorld", nil);
+
+ if (@available(iOS 13.0, *)) {
+ rootView.backgroundColor = [UIColor systemBackgroundColor];
+ } else {
+ rootView.backgroundColor = [UIColor whiteColor];
+ }
+
+ self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
+ UIViewController *rootViewController = [UIViewController new];
+ rootViewController.view = rootView;
+ self.window.rootViewController = rootViewController;
+ [self.window makeKeyAndVisible];
+ return YES;
+}
+
+- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
+{
+#if DEBUG
+ return [[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
+
+@end
diff --git a/template/ios/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json b/template/ios/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json
index 118c98f7..81213230 100644
--- a/template/ios/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json
+++ b/template/ios/HelloWorld/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -2,37 +2,52 @@
"images" : [
{
"idiom" : "iphone",
- "size" : "29x29",
- "scale" : "2x"
+ "scale" : "2x",
+ "size" : "20x20"
},
{
"idiom" : "iphone",
- "size" : "29x29",
- "scale" : "3x"
+ "scale" : "3x",
+ "size" : "20x20"
},
{
"idiom" : "iphone",
- "size" : "40x40",
- "scale" : "2x"
+ "scale" : "2x",
+ "size" : "29x29"
},
{
"idiom" : "iphone",
- "size" : "40x40",
- "scale" : "3x"
+ "scale" : "3x",
+ "size" : "29x29"
},
{
"idiom" : "iphone",
- "size" : "60x60",
- "scale" : "2x"
+ "scale" : "2x",
+ "size" : "40x40"
},
{
"idiom" : "iphone",
- "size" : "60x60",
- "scale" : "3x"
+ "scale" : "3x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "60x60"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "60x60"
+ },
+ {
+ "idiom" : "ios-marketing",
+ "scale" : "1x",
+ "size" : "1024x1024"
}
],
"info" : {
- "version" : 1,
- "author" : "xcode"
+ "author" : "xcode",
+ "version" : 1
}
-}
\ No newline at end of file
+}
diff --git a/template/ios/HelloWorld/main.m b/template/ios/HelloWorld/main.m
index b1df44b9..d645c724 100644
--- a/template/ios/HelloWorld/main.m
+++ b/template/ios/HelloWorld/main.m
@@ -2,7 +2,8 @@
#import "AppDelegate.h"
-int main(int argc, char * argv[]) {
+int main(int argc, char *argv[])
+{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
diff --git a/template/ios/HelloWorldTests/HelloWorldTests.m b/template/ios/HelloWorldTests/HelloWorldTests.m
index eabd5fd1..884d405d 100644
--- a/template/ios/HelloWorldTests/HelloWorldTests.m
+++ b/template/ios/HelloWorldTests/HelloWorldTests.m
@@ -13,7 +13,7 @@ @interface HelloWorldTests : XCTestCase
@implementation HelloWorldTests
-- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
+- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test
{
if (test(view)) {
return YES;
@@ -34,23 +34,25 @@ - (void)testRendersWelcomeScreen
__block NSString *redboxError = nil;
#ifdef DEBUG
- RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
- if (level >= RCTLogLevelError) {
- redboxError = message;
- }
- });
+ RCTSetLogFunction(
+ ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
+ if (level >= RCTLogLevelError) {
+ redboxError = message;
+ }
+ });
#endif
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
- foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
- if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
- return YES;
- }
- return NO;
- }];
+ foundElement = [self findSubviewInView:vc.view
+ matching:^BOOL(UIView *view) {
+ if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
+ return YES;
+ }
+ return NO;
+ }];
}
#ifdef DEBUG
@@ -61,5 +63,4 @@ - (void)testRendersWelcomeScreen
XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
}
-
@end
diff --git a/template/ios/Podfile b/template/ios/Podfile
index a076cea9..01506faf 100644
--- a/template/ios/Podfile
+++ b/template/ios/Podfile
@@ -2,14 +2,21 @@ require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
platform :ios, '11.0'
+install! 'cocoapods', :deterministic_uuids => false
target 'HelloWorld' do
config = use_native_modules!
+ # Flags change depending on the env values.
+ flags = get_default_flags()
+
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods
- :hermes_enabled => false
+ :hermes_enabled => flags[:hermes_enabled],
+ :fabric_enabled => flags[:fabric_enabled],
+ # An absolute path to your application root.
+ :app_path => "#{Pod::Config.instance.installation_root}/.."
)
target 'HelloWorldTests' do
@@ -27,4 +34,4 @@ target 'HelloWorld' do
react_native_post_install(installer)
__apply_Xcode_12_5_M1_post_install_workaround(installer)
end
-end
\ No newline at end of file
+end
diff --git a/template/package.json b/template/package.json
index cbe5efdc..3dd1acf5 100644
--- a/template/package.json
+++ b/template/package.json
@@ -11,21 +11,21 @@
},
"dependencies": {
"react": "17.0.2",
- "react-native": "0.67.4"
+ "react-native": "0.68.0-rc.4"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@babel/runtime": "^7.12.5",
"@react-native-community/eslint-config": "^2.0.0",
"@types/jest": "^26.0.23",
- "@types/react-native": "^0.66.15",
+ "@types/react-native": "^0.67.3",
"@types/react-test-renderer": "^17.0.1",
- "@typescript-eslint/eslint-plugin": "^5.7.0",
- "@typescript-eslint/parser": "^5.7.0",
+ "@typescript-eslint/eslint-plugin": "^5.17.0",
+ "@typescript-eslint/parser": "^5.17.0",
"babel-jest": "^26.6.3",
- "eslint": "^7.14.0",
+ "eslint": "^7.32.0",
"jest": "^26.6.3",
- "metro-react-native-babel-preset": "^0.66.2",
+ "metro-react-native-babel-preset": "^0.67.0",
"react-test-renderer": "17.0.2",
"typescript": "^4.4.4"
},