与现有应用集成
当你从头开始开发新的移动应用时,React Native 非常出色。然而,它也非常适合为现有的原生应用程序添加单个视图或用户流程。只需几步,你就可以添加基于 React Native 的新功能、屏幕、视图等。
具体步骤取决于你目标平台的不同。
- Android (Java 和 Kotlin)
- iOS (Objective-C 和 Swift)
核心概念
将 React Native 组件集成到你的 Android 应用中的关键在于:
- 设置正确的目录结构。
- 安装必要的 NPM 依赖。
- 将 React Native 添加到你的 Gradle 配置。
- 编写你的第一个 React Native 屏幕的 TypeScript 代码。
- 使用 ReactActivity 将 React Native 与你的 Android 代码集成。
- 通过运行 bundler 并查看你的应用运行情况来测试你的集成。
使用社区模板
当你遵循本指南时,我们建议你使用 React Native 社区模板 作为参考。该模板包含一个最小化的 Android 应用,将帮助你理解如何将 React Native 集成到现有的 Android 应用中。
前置条件
遵循关于 设置开发环境 的指南,并使用 不使用框架的 React Native 来配置你的开发环境,以构建用于 Android 的 React Native 应用。
本指南还假设你熟悉 Android 开发的基础,例如创建 Activity 和编辑 AndroidManifest.xml 文件。
1. 设置目录结构
为了确保顺畅的体验,为你的集成后的 React Native 项目创建一个新文件夹,然后将你现有的 Android 项目移动到 /android 子文件夹。
2. 安装 NPM 依赖
进入根目录并运行以下命令:
curl -O https://raw.githubusercontent.com/react-native-community/template/refs/heads/0.75-stable/template/package.json
这将把 package.json 文件从社区模板 复制到你的项目。
接下来,通过运行以下命令安装 NPM 包:
- npm
- Yarn
npm install
yarn install
安装过程已创建一个新的 node_modules 文件夹。此文件夹存储所有构建项目所需的 JavaScript 依赖。
将 node_modules/ 添加到你的 .gitignore 文件(此处为 社区默认文件)。
3. 将 React Native 添加到你的应用
配置 Gradle
React Native 使用 React Native Gradle 插件来配置你的依赖和项目设置。
首先,让我们编辑你的 settings.gradle 文件,通过添加这些行(如 社区模板 所建议):
// 配置用于自动链接的 React Native Gradle Settings 插件
pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
plugins { id("com.facebook.react.settings") }
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
// 如果使用 .gradle.kts 文件:
// extensions.configure<com.facebook.react.ReactSettingsExtension> { autolinkLibrariesFromCommand() }
includeBuild("../node_modules/@react-native/gradle-plugin")
// 在此处包含你现有的 Gradle 模块。
// include(":app")
然后你需要打开顶层的 build.gradle 并包含此行(如 社区模板 所建议):
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
+ classpath("com.facebook.react:react-native-gradle-plugin")
}
}
这确保 React Native Gradle 插件 (RNGP) 在你的项目中可用。
最后,在你的 Application 的 build.gradle 文件中添加这些行(这是一个不同的 build.gradle 文件,通常位于你的 app 文件夹内 - 你可以使用 社区模板文件作为参考):
apply plugin: "com.android.application"
+apply plugin: "com.facebook.react"
repositories {
mavenCentral()
}
dependencies {
// 其他依赖在此处
+ // 注意:我们故意在此处不指定版本号,因为 RNGP 会处理它。
+ // 如果你不使用 RNGP,你将必须手动指定版本。
+ implementation("com.facebook.react:react-android")
+ implementation("com.facebook.react:hermes-android")
}
+react {
+ // 需要启用自动链接 - https://github.com/react-native-community/cli/blob/master/docs/autolinking.md
+ autolinkLibrariesWithApp()
+}
最后,打开你的应用 gradle.properties 文件并添加以下行(此处 社区模板文件作为参考):
+reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
+newArchEnabled=true
+hermesEnabled=true
配置你的 manifest
首先,确保你在 AndroidManifest.xml 中有网络权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MainApplication">
</application>
</manifest>
然后你需要在你的 debug AndroidManifest.xml 中启用 明文流量:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
+ android:usesCleartextTraffic="true"
+ tools:targetApi="28"
/>
</manifest>
通常,此处是来自社区模板的 AndroidManifest.xml 文件作为参考:main 和 debug
这是必需的,因为你的应用将通过 HTTP 与你的本地 bundler Metro 通信。
确保你仅将此添加到你的 debug manifest。
4. 编写 TypeScript 代码
现在我们将实际修改原生 Android 应用以集成 React Native。
我们将编写的第一段代码是将集成到我们应用中的新屏幕的实际 React Native 代码。
创建一个 index.js 文件
首先,在你的 React Native 项目根目录创建一个空的 index.js 文件。
index.js 是 React Native 应用的起点,并且它是始终必需的。它可以是一个导入其他文件的小文件,这些文件是你 React Native 组件或应用的一部分,或者它可以包含所需的所有代码。
我们的 index.js 应该如下所示(此处 社区模板文件作为参考):
import {AppRegistry} from 'react-native';
import App from './App';
AppRegistry.registerComponent('HelloWorld', () => App);
创建一个 App.tsx 文件
让我们创建一个 App.tsx 文件。这是一个 TypeScript 文件,可以包含 JSX 表达式。它包含我们将集成到 Android 应用中的根 React Native 组件(链接):
import React from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
} from 'react-native';
import {
Colors,
DebugInstructions,
Header,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
function App(): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
<View
style={{
backgroundColor: isDarkMode
? Colors.black
: Colors.white,
padding: 24,
}}>
<Text style={styles.title}>Step One</Text>
<Text>
Edit <Text style={styles.bold}>App.tsx</Text> to
change this screen and see your edits.
</Text>
<Text style={styles.title}>See your changes</Text>
<ReloadInstructions />
<Text style={styles.title}>Debug</Text>
<DebugInstructions />
</View>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
title: {
fontSize: 24,
fontWeight: '600',
},
bold: {
fontWeight: '700',
},
});
export default App;
此处 社区模板文件作为参考
5. 与你的 Android 代码集成
我们现在需要添加一些原生代码以便启动 React Native 运行时并告诉它渲染我们的 React 组件。
更新你的 Application 类
首先,我们需要更新你的 Application 类以正确初始化 React Native,如下所示:
- Java
- Kotlin
package <your-package-here>;
import android.app.Application;
+import com.facebook.react.PackageList;
+import com.facebook.react.ReactApplication;
+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.facebook.react.defaults.DefaultReactNativeHost;
+import com.facebook.soloader.SoLoader;
+import com.facebook.react.soloader.OpenSourceMergedSoMapping
+import java.util.List;
-class MainApplication extends Application {
+class MainApplication extends Application implements ReactApplication {
+ @Override
+ public ReactNativeHost getReactNativeHost() {
+ return new DefaultReactNativeHost(this) {
+ @Override
+ protected List<ReactPackage> getPackages() { return new PackageList(this).getPackages(); }
+ @Override
+ protected String getJSMainModuleName() { return "index"; }
+ @Override
+ public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; }
+ @Override
+ protected boolean isNewArchEnabled() { return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; }
+ @Override
+ protected Boolean isHermesEnabled() { return BuildConfig.IS_HERMES_ENABLED; }
+ };
+ }
+ @Override
+ public ReactHost getReactHost() {
+ return DefaultReactHost.getDefaultReactHost(getApplicationContext(), getReactNativeHost());
+ }
@Override
public void onCreate() {
super.onCreate();
+ SoLoader.init(this, OpenSourceMergedSoMapping);
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+ DefaultNewArchitectureEntryPoint.load();
+ }
}
}
// package <your-package-here>
import android.app.Application
+import com.facebook.react.PackageList
+import com.facebook.react.ReactApplication
+import com.facebook.react.ReactHost
+import com.facebook.react.ReactNativeHost
+import com.facebook.react.ReactPackage
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
+import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
+import com.facebook.react.defaults.DefaultReactNativeHost
+import com.facebook.soloader.SoLoader
+import com.facebook.react.soloader.OpenSourceMergedSoMapping
-class MainApplication : Application() {
+class MainApplication : Application(), ReactApplication {
+ override val reactNativeHost: ReactNativeHost =
+ object : DefaultReactNativeHost(this) {
+ override fun getPackages(): List<ReactPackage> = PackageList(this).packages
+ 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(applicationContext, reactNativeHost)
override fun onCreate() {
super.onCreate()
+ SoLoader.init(this, OpenSourceMergedSoMapping)
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+ load()
+ }
}
}
通常,此处 MainApplication.kt 社区模板文件作为参考
创建一个 ReactActivity
最后,我们需要创建一个新的 Activity,它将继承 ReactActivity 并承载 React Native 代码。此 Activity 将负责启动 React Native 运行时并渲染 React 组件。
- Java
- Kotlin
// package <your-package-here>;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactActivityDelegate;
public class MyReactActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "HelloWorld";
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new DefaultReactActivityDelegate(this, getMainComponentName(), DefaultNewArchitectureEntryPoint.getFabricEnabled());
}
}
// package <your-package-here>
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
class MyReactActivity : ReactActivity() {
override fun getMainComponentName(): String = "HelloWorld"
override fun createReactActivityDelegate(): ReactActivityDelegate =
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
}
通常,此处 MainActivity.kt 社区模板文件作为参考
每当你创建一个新的 Activity,你需要将其添加到你的 AndroidManifest.xml 文件。你还需要将 MyReactActivity 的主题设置为 Theme.AppCompat.Light.NoActionBar(或任何非 ActionBar 主题),否则你的应用将在你的 React Native 屏幕顶部渲染一个 ActionBar:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MainApplication">
+ <activity
+ android:name=".MyReactActivity"
+ android:label="@string/app_name"
+ android:theme="@style/Theme.AppCompat.Light.NoActionBar">
+ </activity>
</application>
</manifest>
现在你的 Activity 已准备好运行一些 JavaScript 代码。
6. 测试你的集成
你已经完成了将 React Native 集成到应用程序中的所有基本步骤。现在我们将启动 Metro bundler 将你的 TypeScript 应用程序代码构建为一个 bundle。Metro 的 HTTP 服务器将开发者环境上 localhost 的 bundle 共享给模拟器或设备。这允许进行 热重载。
首先,你需要在项目的根目录创建一个 metro.config.js 文件,如下所示:
const {getDefaultConfig} = require('@react-native/metro-config');
module.exports = getDefaultConfig(__dirname);
你可以查看社区模板文件中的 metro.config.js 文件 作为参考。
一旦配置文件就位,你就可以运行 bundler 了。在你的项目根目录运行以下命令:
- npm
- Yarn
npm start
yarn start
现在像往常一样构建并运行你的 Android 应用。
一旦你进入应用内由 React 驱动的 Activity,它应该会从开发服务器加载 JavaScript 代码并显示:

在 Android Studio 中创建发布构建
你也可以使用 Android Studio 来创建你的发布构建!这就像创建你之前存在的原生 Android 应用的发布构建一样快。
React Native Gradle 插件将负责把 JS 代码打包进你的 APK/App Bundle 中。
如果你不使用 Android Studio,你可以使用以下命令创建发布构建:
cd android
# 用于发布 APK
./gradlew :app:assembleRelease
# 用于发布 AAB
./gradlew :app:bundleRelease
接下来做什么?
此时你可以像往常一样继续开发你的应用。参考我们的 调试 和 部署 文档以了解更多关于使用 React Native 工作的信息。
关键概念
将 React Native 组件集成到 iOS 应用程序中的关键在于:
- 设置正确的目录结构。
- 安装必要的 NPM 依赖项。
- 将 React Native 添加到你的 Podfile 配置中。
- 为你的第一个 React Native 屏幕编写 TypeScript 代码。
- 使用
RCTRootView将 React Native 与你的 iOS 代码集成。 - 通过运行 bundler 并查看你的应用实际运行来测试你的集成。
使用社区模板
在遵循本指南时,我们建议你使用 React Native Community Template 作为参考。该模板包含一个 最小化 iOS 应用,并将帮助你了解如何将 React Native 集成到现有的 iOS 应用中。
先决条件
遵循 设置开发环境 的指南,并使用 不使用框架的 React Native 来配置你的开发环境,以便为 iOS 构建 React Native 应用。
本指南还假设你熟悉 iOS 开发的基础知识,例如创建 UIViewController 和编辑 Podfile 文件。
1. 设置目录结构
为了确保体验顺畅,为你的集成 React Native 项目创建一个新文件夹,然后将 现有的 iOS 项目 移动到 /ios 子文件夹中。
2. 安装 NPM 依赖
进入根目录并运行以下命令:
curl -O https://raw.githubusercontent.com/react-native-community/template/refs/heads/0.77-stable/template/package.json
这会将 社区模板中的 package.json 文件 复制到你的项目。
接下来,通过运行以下命令安装 NPM 包:
- npm
- Yarn
npm install
yarn install
安装过程创建了一个新的 node_modules 文件夹。此文件夹存储构建项目所需的所有 JavaScript 依赖项。
将 node_modules/ 添加到你的 .gitignore 文件中(这里是 社区默认文件)。
3. 安装开发工具
Xcode 命令行工具
安装命令行工具。在 Xcode 菜单中选择 设置...(或偏好设置...)。转到位置面板,通过在命令行工具下拉菜单中选择最新版本来安装工具。

CocoaPods
CocoaPods 是一个用于 iOS 和 macOS 开发的包管理工具。我们使用它将实际的 React Native 框架代码本地添加到当前项目中。
我们建议使用 Homebrew 安装 CocoaPods:
brew install cocoapods
4. 将 React Native 添加到你的应用
配置 CocoaPods
要配置 CocoaPods,我们需要两个文件:
- 一个 Gemfile,定义我们需要哪些 Ruby 依赖项。
- 一个 Podfile,定义如何正确安装我们的依赖项。
对于 Gemfile,进入项目的根目录并运行此命令
curl -O https://raw.githubusercontent.com/react-native-community/template/refs/heads/0.77-stable/template/Gemfile
这将从模板下载 Gemfile。
同样,对于 Podfile,进入项目的 ios 文件夹并运行
curl -O https://raw.githubusercontent.com/react-native-community/template/refs/heads/0.77-stable/template/ios/Podfile
请使用社区模板作为 Gemfile 和 Podfile 的参考点。
现在,我们需要运行几个额外的命令来安装 Ruby gems 和 Pods。
导航到 ios 文件夹并运行以下命令:
bundle install
bundle exec pod install
第一个命令将安装 Ruby 依赖项,第二个命令将实际把 React Native 代码集成到你的应用程序中,以便你的 iOS 文件可以导入 React Native 头文件。
5. 编写 TypeScript 代码
现在我们将实际修改原生 iOS 应用程序以集成 React Native。
我们将编写的第一段代码是实际用于新屏幕的 React Native 代码,该屏幕将集成到我们的应用程序中。
创建 index.js 文件
首先,在你的 React Native 项目根目录中创建一个空的 index.js 文件。
index.js 是 React Native 应用程序的起点,并且始终是必需的。它可以是一个 import 其他属于你 React Native 组件或应用程序部分的文件的小文件,也可以包含所需的所有代码。
我们的 index.js 应该如下所示(此处参考 社区模板文件):
import {AppRegistry} from 'react-native';
import App from './App';
AppRegistry.registerComponent('HelloWorld', () => App);
创建 App.tsx 文件
让我们创建一个 App.tsx 文件。这是一个 TypeScript 文件,可以包含 JSX 表达式。它包含我们将集成到 iOS 应用程序中的根 React Native 组件(链接):
import React from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
} from 'react-native';
import {
Colors,
DebugInstructions,
Header,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
function App(): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
<View
style={{
backgroundColor: isDarkMode
? Colors.black
: Colors.white,
padding: 24,
}}>
<Text style={styles.title}>Step One</Text>
<Text>
Edit <Text style={styles.bold}>App.tsx</Text> to
change this screen and see your edits.
</Text>
<Text style={styles.title}>See your changes</Text>
<ReloadInstructions />
<Text style={styles.title}>Debug</Text>
<DebugInstructions />
</View>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
title: {
fontSize: 24,
fontWeight: '600',
},
bold: {
fontWeight: '700',
},
});
export default App;
此处参考 社区模板文件
5. 与你的 iOS 代码集成
我们现在需要添加一些原生代码以启动 React Native 运行时并告诉它渲染我们的 React 组件。
要求
React Native 应该与 AppDelegate 一起工作。以下部分假设你的 AppDelegate 如下所示:
- ObjectiveC
- Swift
#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate {
UIWindow *window;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
window = [UIWindow new];
window.rootViewController = [ViewController new];
[window makeKeyAndVisible];
return YES;
}
@end
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 应用程序启动后的自定义覆盖点。
window = UIWindow()
window?.rootViewController = ViewController()
window?.makeKeyAndVisible()
return true
}
}
更新 AppDelegate 类
首先,我们需要扩展 AppDelegate 以继承 React Native 提供的类之一:RCTAppDelegate。
- ObjectiveC
- Swift
为了实现这一点,我们必须修改 AppDelegate.h 文件和 AppDelegate.m 文件:
- 打开
AppDelegate.h文件并按如下方式修改它(参见官方模板的 AppDelegate.h 作为参考):
#import <UIKit/UIKit.h>
+#import <React-RCTAppDelegate/RCTAppDelegate.h>
-@interface AppDelegate : UIResponder <UIApplicationDelegate>
+@interface AppDelegate : RCTAppDelegate
@end
- 打开
AppDelegate.mm文件并按如下方式修改它(参见官方模板的 AppDelegate.mm 作为参考)
#import "AppDelegate.h"
#import "ViewController.h"
+#import <React/RCTBundleURLProvider.h>
@interface AppDelegate ()
@end
@implementation AppDelegate {
UIWindow *window;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ self.automaticallyLoadReactNativeWindow = NO;
+ return [super application:application didFinishLaunchingWithOptions:launchOptions];
window = [UIWindow new];
window.rootViewController = [ViewController new];
[window makeKeyAndVisible];
return YES;
}
+- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
+{
+ return [self bundleURL];
+}
+- (NSURL *)bundleURL
+{
+#if DEBUG
+ return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
+#else
+ return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
+#endif
+}
@end
让我们看看上面的代码:
- 我们继承自
RCTAppDelegate并调用RCTAppDelegate的application:didFinishLaunchingWithOptions。这将所有 React Native 初始化过程委托给基类。 - 我们通过将
automaticallyLoadReactNativeWindow设置为NO来自定义RCTAppDelegate。此步骤指示 React Native 应用正在处理UIWindow,React Native 不应担心这一点。 - 方法
sourceURLForBridge:和bundleURL由应用用于告诉 React Native 在哪里可以找到需要渲染的 JS bundle。sourceURLForBridge:来自旧架构,你可以看到它将决策推迟到bundleURL方法,这是新架构所需的。
为了实现这一点,我们必须修改 AppDelegate.swift
- 打开
AppDelegate.swift文件并按如下方式修改它(参见官方模板的 AppDelegate.swift 作为参考):
import UIKit
+import React_RCTAppDelegate
@main
-class AppDelegate: UIResponder, UIApplicationDelegate {
+class AppDelegate: RCTAppDelegate {
- var window: UIWindow?
- func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 应用程序启动后的自定义覆盖点。
+ self.automaticallyLoadReactNativeWindow = false
+ super.application(application, didFinishLaunchingWithOptions: launchOptions)
window = UIWindow()
- window?.rootViewController = ViewController()
- window?.makeKeyAndVisible()
+ window.rootViewController = ViewController()
+ window.makeKeyAndVisible()
return true
}
+ override func sourceURL(for bridge: RCTBridge) -> URL? {
+ self.bundleURL()
+ }
+ override func bundleURL() -> URL? {
+#if DEBUG
+ RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
+#else
+ Bundle.main.url(forResource: "main", withExtension: "jsbundle")
+#endif
+ }
}
让我们看看上面的代码:
- 我们继承自
RCTAppDelegate并调用RCTAppDelegate的application(_:didFinishLaunchingWithOptions:)。这将所有 React Native 初始化过程委托给基类。 - 我们通过将
automaticallyLoadReactNativeWindow设置为false来自定义RCTAppDelegate。此步骤指示 React Native 应用正在处理UIWindow,React Native 不应担心这一点。 - 方法
sourceURLForBridge(for:)和bundleURL()由应用用于告诉 React Native 在哪里可以找到需要渲染的 JS bundle。sourceURLForBridge(for:)来自旧架构,你可以看到它将决策推迟到bundleURL()方法,这是新架构所需的。
在 rootViewController 中呈现 React Native 视图
最后,我们可以呈现我们的 React Native 视图。为此,我们需要一个新的 View Controller,它可以托管一个我们可以加载 JS 内容的视图。
- 在 Xcode 中,让我们创建一个新的
UIViewController(我们称之为ReactViewController)。 - 让初始
ViewController呈现ReactViewController。有几种方法可以做到这一点,具体取决于你的应用。对于此示例,我们假设你有一个按钮以模态方式呈现 React Native。
- ObjectiveC
- Swift
#import "ViewController.h"
+#import "ReactViewController.h"
@interface ViewController ()
@end
- @implementation ViewController
+@implementation ViewController {
+ ReactViewController *reactViewController;
}
- (void)viewDidLoad {
[super viewDidLoad];
// 加载视图后进行任何额外的设置。
self.view.backgroundColor = UIColor.systemBackgroundColor;
+ UIButton *button = [UIButton new];
+ [button setTitle:@"Open React Native" forState:UIControlStateNormal];
+ [button setTitleColor:UIColor.systemBlueColor forState:UIControlStateNormal];
+ [button setTitleColor:UIColor.blueColor forState:UIControlStateHighlighted];
+ [button addTarget:self action:@selector(presentReactNative) forControlEvents:UIControlEventTouchUpInside];
+ [self.view addSubview:button];
+ button.translatesAutoresizingMaskIntoConstraints = NO;
+ [NSLayoutConstraint activateConstraints:@[
+ [button.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
+ [button.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
+ [button.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
+ [button.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
+ ]];
}
+- (void)presentReactNative
+{
+ if (reactViewController == NULL) {
+ reactViewController = [ReactViewController new];
+ }
+ [self presentViewController:reactViewController animated:YES completion:nil];
+}
@end
import UIKit
class ViewController: UIViewController {
+ var reactViewController: ReactViewController?
override func viewDidLoad() {
super.viewDidLoad()
// 加载视图后进行任何额外的设置。
self.view.backgroundColor = .systemBackground
+ let button = UIButton()
+ button.setTitle("Open React Native", for: .normal)
+ button.setTitleColor(.systemBlue, for: .normal)
+ button.setTitleColor(.blue, for: .highlighted)
+ button.addAction(UIAction { [weak self] _ in
+ guard let self else { return }
+ if reactViewController == nil {
+ reactViewController = ReactViewController()
+ }
+ present(reactViewController!, animated: true)
+ }, for: .touchUpInside)
+ self.view.addSubview(button)
+
+ button.translatesAutoresizingMaskIntoConstraints = false
+ NSLayoutConstraint.activate([
+ button.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
+ button.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
+ button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
+ button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
+ ])
}
}
- 按如下方式更新
ReactViewController代码:
- ObjectiveC
- Swift
#import "ReactViewController.h"
+#import <React-RCTAppDelegate/RCTRootViewFactory.h>
+#import <React-RCTAppDelegate/RCTAppDelegate.h>
@interface ReactViewController ()
@end
@implementation ReactViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 加载视图后进行任何额外的设置。
+ RCTRootViewFactory *factory = ((RCTAppDelegate *)RCTSharedApplication().delegate).rootViewFactory;
+ self.view = [factory viewWithModuleName:@"HelloWorld"];
}
@end
import UIKit
+import React_RCTAppDelegate
class ReactViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
+ let factory = (RCTSharedApplication()?.delegate as? RCTAppDelegate)?.rootViewFactory
+ self.view = factory?.view(withModuleName: "HelloWorld")
}
}
- 确保禁用 Sandbox 脚本。为了实现这一点,在 Xcode 中,点击你的应用,然后点击构建设置。过滤脚本并将
User Script Sandboxing设置为NO。此步骤需要正确切换我们随 React Native 提供的 Hermes 引擎 的 Debug 和 Release 版本。
;
6. 测试你的集成
你已经完成了将 React Native 集成到应用程序中的所有基本步骤。现在我们将启动 Metro bundler 将你的 TypeScript 应用程序代码构建为一个 bundle。Metro 的 HTTP 服务器将开发者环境 localhost 上的 bundle 共享给模拟器或设备。这允许 热重载。
首先,你需要在项目的根目录创建一个 metro.config.js 文件,如下所示:
const {getDefaultConfig} = require('@react-native/metro-config');
module.exports = getDefaultConfig(__dirname);
你可以查看 Community 模板文件中的 metro.config.js 文件 作为参考。
一旦配置文件就位,你就可以运行 bundler 了。在项目根目录运行以下命令:
- npm
- Yarn
npm start
yarn start
现在像往常一样构建并运行你的 iOS 应用。
一旦你进入应用内由 React 驱动的 Activity,它应该会从开发服务器加载 JavaScript 代码并显示:

在 Xcode 中创建发布构建
你也可以使用 Xcode 来创建发布构建!唯一额外的步骤是添加一个脚本,该脚本在应用构建时执行,将你的 JS 和图片打包到 iOS 应用程序中。
- 在 Xcode 中,选择你的应用程序
- 点击
Build Phases - 点击左上角的
+并选择New Run Script Phase - 点击
Run Script行并将脚本重命名为Bundle React Native code and images - 在文本框中粘贴以下脚本
set -e
WITH_ENVIRONMENT="$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh"
REACT_NATIVE_XCODE="$REACT_NATIVE_PATH/scripts/react-native-xcode.sh"
/bin/sh -c "$WITH_ENVIRONMENT $REACT_NATIVE_XCODE"
- 将该脚本拖放到名为
[CP] Embed Pods Frameworks的脚本之前。
现在,如果你为 Release 构建你的应用,它将按预期工作。
接下来做什么?
此时你可以像往常一样继续开发你的应用。参考我们的 调试 和 部署 文档以了解更多关于使用 React Native 工作的内容。