首先我们前提是已经安装了React Native所需要的工具,Node.js 等。
项目
1.首先我们有这样一个项目:RNDemo ,并使用目录级RNTestDemo/RNDemo/RNDemo.xcodeproj
2.之后向RNTestDemo中添加依赖包RNTestDemo
打开文件夹RNTestDemo,这个目录作为整个项目的根目录使用,
依赖包
react Native的植入过程同时需要React和React Native两个node依赖包。
package.json
我们把具体的依赖包记录在package.json
文件中。如果项目根目录中没有这个文件,那就自己创建一个。
对于一个典型的react native项目来说,一般
package.json
和index.iOS.js
等文件会放在项目的根目录下。而ios相关的原生代码会放在一个名为ios/(这里是指我们的RNDemo文件夹)
的子目录中,这里也同时放着你的Xcode项目文件(.xcodeproj
)。
下面是一个最简单的package.json
的内容示例。
示例中的
version
字段没有太大意义(除非你要把你的项目发布到npm仓库)。scripts
中是用于启动packager服务的命令。dependencies中的react和react-native的版本取决于你的具体需求。一般来说我们推荐使用最新版本。你可以使用npm info react
和npm info react-native
来查看当前的最新版本。另外,react-native对react的版本有严格要求,高于或低于某个范围都不可以。本文无法在这里列出所有react native和对应的react版本要求,只能提醒读者先尝试执行npm install,然后注意观察安装过程中的报错信息,例如require react@某.某.某版本, but none was installed
,然后根据这样的提示,执行npm i -S react@某.某.某版本
。
{
"name": "RNDemo",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"dependencies": {
"react": "15.4.2",
"react-native": "0.41.2"
}
}
使用npm(node包管理器,Node package manager)来安装React和React Native模块。这些模块会被安装到项目根目录下的node_modules/
目录中。 在包含有package.json文件的目录(一般也就是项目根目录)中运行下列命令来安装:
$ npm install
在漫长的安装过后,我们看到了node_modules文件夹
这个
导入React Native框架
这里Libstdc++.tbd这个可能是必要的,
向Edit Scheme的Build中添加React,并拖拽到最上位置,并取消勾选Parallelize Build选项,这一步很关键,因为项目需要先编译React.a文件
Build Settings 中需要设置
Other Linker Flags -ObjC
可能需要设置
Header Search Paths "$(SRCROOT)/../node_modules/react-native/React" 并设置为 recursive
现在我们已经万事俱备了.
代码集成
现在我们已经准备好了所有依赖,可以开始着手修改原生代码来把React Native真正植入到应用中了。在我们的2048示例中,首先尝试添加一个显示有"High Score"(得分排行榜)的React Native页面。
React Native组件
我们首先要写的是"High Score"(得分排行榜)的JavaScript端的代码。
创建一个index.ios.js
文件
首先创建一个空的index.ios.js
文件。一般来说我们把它放置在项目根目录下。
index.ios.js
是React Native应用在iOS上的入口文件。而且它是不可或缺的!它可以是个很简单的文件,简单到可以只包含一行require/import
导入语句。本教程中为了简单示范,把全部的代码都写到了index.ios.js
里(当然实际开发中我们并不推荐这样做)。
# 在项目根目录执行以下命令创建文件:
$ touch index.ios.js
添加你自己的React Native代码
在index.ios.js
中添加你自己的组件。这里我们只是简单的添加一个<Text>
组件,然后用一个带有样式的<View>
组件把它包起来。
'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);
RNHighScores
是整体js模块(即你所有的js代码)的名称。你在iOS原生代码中添加React Native视图时会用到这个名称。
The Magic: RCTRootView
现在我们已经在index.ios.js
中创建了React Native组件,下一步就是把这个组件添加给一个新的或已有的ViewController
。 The easiest path to take is to optionally create an event path to your component and then add that component to an existing ViewController
.
We will tie our React Native component with a new native view in the ViewController
that will actually host it called RCTRootView
.
Create an Event Path
You can add a new link on the main game menu to Go to the "High Score" React Native page.
事件处理
We will now add an event handler from the menu link. A method will be added to the main ViewController
of your application. This is where RCTRootView
comes into play.
When you build a React Native application, you use the React Native packager to create an index.ios.bundle
that will be served by the React Native server. Inside index.ios.bundle
will be our RNHighScore
module. So, we need to point our RCTRootView
to the location of the index.ios.bundle
resource (via NSURL
) and tie it to the module.
We will, for debugging purposes, log that the event handler was invoked. Then, we will create a string with the location of our React Native code that exists inside the index.ios.bundle
. Finally, we will create the main RCTRootView
. Notice how we provide RNHighScores
as the moduleName
that we created above when writing the code for our React Native component.
首先导入RCTRootView
的头文件。
#import <React/RCTRootView.h>
这里的
initialProperties
are here for illustration purposes so we have some data for our high score screen. In our React Native component, we will usethis.props
to get access to that data.
- (IBAction)highScoreButtonPressed:(id)sender {
NSLog(@"High Score Button Pressed");
NSURL *jsCodeLocation = [NSURL
URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios"];
RCTRootView *rootView =
[[RCTRootView alloc] initWithBundleURL : jsCodeLocation
moduleName : @"RNHighScores"
initialProperties :
@{
@"scores" : @[
@{
@"name" : @"Alex",
@"value": @"42"
},
@{
@"name" : @"Joel",
@"value": @"10"
}
]
}
launchOptions : nil];
UIViewController *vc = [[UIViewController alloc] init];
vc.view = rootView;
[self presentViewController:vc animated:YES completion:nil];
}
测试植入结果
You have now done all the basic steps to integrate React Native with your current application. Now we will start the React Native packager to build the index.ios.bundle
packager and the server running on localhost
to serve it.
App Transport Security
Apple has blocked implicit cleartext HTTP resource loading. So we need to add the following our project's Info.plist
(or equivalent) file.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
手动命令行运行,也可以不执行以下代码,直接Xcode 运行
运行Packager
# From the root of your project, where the `node_modules` directory is located.
$ npm start
运行应用
如果你使用的是Xcode,那么照常编译和运行应用即可。如果你没有使用Xcode(但是你仍然必须安装Xcode),则可以在命令行中使用以下命令来运行应用:
# 在项目的根目录中执行:
$ react-native run-ios
Bingo!!!!!!!!!!
PS:
http://reactnative.cn/docs/0.41/integration-with-existing-apps.html#content