一、场景描述
针对目前项目需求,部分功能需要动态热部署,因此考虑使用React Native。下面有个Demo介绍原生iOS项目是如何与React Native集成的。先贴下React Native中文网是官方教程:React Native嵌入到现有原生应用。
对老项目来说,官方推荐使用第三方包管理器CoCoaPods来自动集成,但是考虑到目前我们项目中没有使用CoCoaPods,原因如下:
1、CoCoaPods 克隆第三方代码简直是慢
2、CoCoaPods会自动创建一些目录,不利于项目管理。
综上所述,因此采用手动集成,下面介绍手动集成方法。
二、手动集成相关步骤
1、用Xcode创建一个原生的iOS项目
打开Xcode -> Create a new Xcode project -> Single View Application -> Demo-ReactnativeIOS
目前,我们的已经创建好了一个iOS项目Demo-ReactnativeIOS,接下来就是集成React Native的步骤了。
2、安装react-native
在Demo-ReactnativeIOS项目目录建一个reactnative目录,用于存放我们的react-native相关文件,再创建一个package.json文件,用于初始化react-native。
// package.json
{
"name": "Demo-ReactnativeIOS",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"dependencies": {
"react": "15.4.1",
"react-native": "0.39.2"
}
}
执行安装:
$ cd reactnative
$ npm install
安装成功后,reactnative目录会产生一个node_modules,里面就是react-native所有依赖的项目包。安装的过程中如果出现一些警告WARN,这个没关系,是有些第三方库没有及时更新的原因。
3、创建index.ios.js文件
在reactnative目录下创建 index.ios.js 文件:
"use strict";
import React from "react";
import { AppRegistry, StyleSheet, Text, View } from "react-native";
class RNHighScores extends React.Component {
render() {
var contents = this.props["scores"].map(score => (
<Text key={score.name}>
{score.name}:{score.value}
{"\n"}
</Text>
));
return (
<View style={styles.container}>
<Text style={styles.highScoresTitle}>2048 High Scores!</Text>
<Text style={styles.scores}>{contents}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#FFFFFF"
},
highScoresTitle: {
fontSize: 20,
textAlign: "center",
margin: 10
},
scores: {
textAlign: "center",
color: "#333333",
marginBottom: 5
}
});
// 整体js模块的名称
AppRegistry.registerComponent("RNHighScores", () => RNHighScores);
index.ios.js这个就是js的初始化入口文件。到这一步,我们已经完成react-native的准备工作,接下来就是开始集成了。
4、原生iOS项目手动集成react-native
- 添加react-native工程文件:由于项目没有使用Cocoapods进行第三方依赖包管理,所有我们需要手动将react-native工程包添加到我们的原生ios工程中。打开 reactnative/node_modules/react-native 目录,找到相关的项目包,将React相关的工程包手动添加到项目中:
添加 `react-native/React/React.xcodeproj`到项目中
添加 `react-native/Libraries/Network/RCTNetwork.xcodeproj`到项目中
添加 `react-native/Libraries/Text/RCTText.xcodeproj`到项目中
添加 `react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj`到项目中
添加 `react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj`到项目中
添加完成如下图:
到这一步,我们已经将React相关工程包手动添加到Demo-ReactnativeIOS工程项目中。目前我们只添加了5个React工程包,如果后续开发中还需要其他工程包,按第4步依次添加就可以。
- 添加相关frameworks文件: 接下来要将相关的frameworks文件添加到工程中, ReactnativeIOS -> TARGETS -> ReactnativeIOS -> Build Phases -> Link Binary With Libraries 。
点击 + 号,将所有 .a 文件(除了 “***-tvOS.a” 结尾)选中并添加。
- 添加libc++.tbd文件
- 添加搜索头文件的地址 Demo-ReactnativeIOS -> TARGETS -> Demo-ReactnativeIOS -> Build Settings -> Header Search Paths ,添加一条 $(SRCROOT)/reactnative/node_modules/react-native/React ,选择 recursive
- 添加 “Swift-OC-Bridging-Header.h” 桥接文件 和 “-ObjC” :(如果项目是Swift编写的话,还要添加下面两步配置,如果是OC的话,直接跳过这一步设置)
(1) Demo-ReactnativeIOS -> TARGETS -> Demo-ReactnativeIOS -> Build Settings -> Objective-C Bridging Header,添加一条 $(PROJECT_DIR)/Demo-ReactnativeIOS/Swift-OC-Bridging-Header.h
(2) Demo-ReactnativeIOS -> TARGETS -> Demo-ReactnativeIOS -> Build Settings -> Other Linker Flags, 添加一条 “-ObjC”
这样我们就react-native集成到现有的ios工程中。
5、添加react-native应用
我们在原生ios应用中添加一个视图容器,用于展示react-native实现的内容。
@IBAction func jump_Click(_ sender: Any) {
// 加载资源文件
let jsCodeLocation = URL(string: "http://localhost:8081/index.ios.bundle?platform=ios")
let mockData:NSDictionary = ["scores":
[
["name":"Alex", "value":"42"],
["name":"Joel", "value":"10"]
]
]
// 创建RN交互容器视图
let rootView = RCTRootView(
bundleURL: jsCodeLocation,
moduleName: "RNHighScores",
initialProperties: mockData as [NSObject : AnyObject],
launchOptions: nil
)
let vc = UIViewController()
vc.view = rootView
self.present(vc, animated: true, completion: nil)
}
到这一步,我们所有的集成工作已经完成,接下来就是运行项目。
6、启动RN开发服务器
在运行我们的项目之前,我们需要先启动我们的开发服务器。进入 reactnative目录 ,然后启动。
$ cd reactnative
$ react-native start
当看到终端中出现React packager ready,标志着我们的服务已经开启了。
7、更新App Transport Security
直接运行项目会报 Could not connect to development server 错误,官网中有这段话:
在iOS 9以上的系统中,除非明确指明,否则应用无法通过http协议连接到localhost主机。 我们建议你在Info.plist文件中将localhost列为App Transport Security的例外。 如果不这样做,在尝试通过http连接到服务器时,会遭遇这个错误 - Could not connect to development server.
打开工程中的 Info.list 文件,添加下面配置即可:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
8、运行iOS项目
通过Xcode点击项目或者 command + R 运行项目,顺利的话就会出现如下画面。
Demo下载地址:Demo-ReactnativeIOS
三、总结:
在手动集成的过程中,要注意Xcode一些相关的参数配置,以及搭建基本的 React Native 开发环境(Homebrew、Node等)、网页HTML开发。
相关链接地址:
React Native 中文网HTML 教程