热门搜索 :
考研考公
您的当前位置:首页正文

原生 iOS 项目集成 React Native

来源:东饰资讯网

0. 安装 CocoaPods

iOS 开发者可以跳过这一步。

0.0 使用 rvm 安装/更新 ruby 环境

安装 cocoapods 对 ruby 版本有要求

$ curl -L https://get.rvm.io | bash -s stable
$ source ~/.rvm/scripts/rvm
// 查看远程 ruby 版本
$ rvm list known
// 查看本地 ruby 版本
$ rvm list
$ rvm install 2.3.0

0.1 使用 gem 安装 cocoapods

如要修改 gem 的镜像地址

$ gem sources -l
// 删除已有的源地址
$ gem sources -r https://rubygems.org/
// 添加需要的源地址
$ gem sources -a https://ruby.taobao.org/
$ gem sources -l

安装 cocoapods

$ gem install cocospods
$ cd ~/.cocoapods/repos/
$ git clone  master

顺利的话安装 ruby 和 cocoapods 两步都会成功,如果失败了可以针对具体问题去网上搜索相关教程或解决方案。这里不详述。

1. 创建/修改 iOS 项目

集成 React Native 要求 iOS 系统版本不小于 7.0。

2. 添加 package.json

{
  "name": "react-native-sample",
  "version": "0.0.1",
  "description": "sample of react native embedding ios",
  "main": "index.ios.js",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "author": "danke77",
  "license": "ISC",
  "dependencies": {
    "react": "^15.3.2",
    "react-native": "^0.35.0"
  },
  "devDependencies": {
  }
}

执行 npm install 就可以安装 dependencies 下的 npm 组件了。

这个时候在 iOS 项目根目录就生成了 node_modules/ 文件夹,里面就是一些用到的组件。

.gitignore 中添加

# node.js
node_modules/
npm-debug.log

执行 react-native upgrade 可以更新已有组件。

3. 添加 index.ios.js

在 iOS 项目根目录创建目录 js/,js 相关的代码就放在这个文件夹下。

js/ 下添加 App.js,内容如下

import React, { Component } from 'react'
import { View, Text, StyleSheet } from 'react-native'

export default class extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.text}>
          Hello React Native!
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#ffffff'
  },
  text: {
    fontSize: 20,
    color: '#333333'
  }
})

在 iOS 项目根目录新建文件 index.ios.js,内容如下

import { AppRegistry } from 'react-native'
import App from './js/App'

AppRegistry.registerComponent('navigation', () => App)

这里的 navigation 一般会根据模块功能命名,后面还会用到。

当然也可以把 App.js 的内容写在 index.ios.js 里,但这样写更清晰一些,尤其是项目大了文件多的情况。

4. 用 cocoapods 集成 React Native

在 iOS 项目根目录的 Podfile 文件(没有则创建)添加 React Native 相关内容

target 'HelloReactNative' do
platform :ios, '7.0'

source 

# 这里的 :path 内容取决于 node_modules/ 实际所在的位置
pod 'React', :path => ‘./node_modules/react-native', :subspecs => [
    'Core',
    'RCTText',
    'RCTImage',
    'RCTNetwork',
    'RCTWebSocket', # needed for debugging
    # Add any other subspecs you want to use in your project
]

要在这里添加项目需要的依赖,如要使用 React Native 的 Text 则必须要添加 RCTText 依赖(pod 'React/RCTText')。

然后在根目录执行 pod install

5. React Native 相关的 ViewController

创建一个用于容纳 React Native 组件的 ViewController,并添加 RCTRootView,它会把 React Native 组件解析成原生的 UIView。

#import "HelloReactViewController.h"
#import <RCTRootView.h>

@interface HelloReactViewController ()

@end

@implementation HelloReactViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
#ifdef DEBUG
    NSURL * jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
#else
    NSURL * jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"bundle/index.ios" withExtension:@"bundle"];
#endif
    
    RCTRootView * rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                         moduleName:@"navigation"
                                                  initialProperties:nil
                                                      launchOptions:nil];
                                                                                                     
    self.view = rootView;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

jsCodeLocation 是 React Native 资源加载的路径,可以通过网络加载本地的资源文件(主要用于本地调试),或者将其打包成 js bundle 文件(用于发布正式包)。

moduleName 对应 React Native 组件的入口,必须和前面的 AppRegistry.registerComponent('navigation', () => App) 里的 navigation 对应。

6. 启动服务

debug 模式下需要启动 package server,在 package.json 所在目录(一般为项目根目录)下执行 npm start,它等效于 package.jsonscripts 下的 node node_modules/react-native/local-cli/cli.js start,相当于启动一个本地服务。

Terminal 显示如下表示服务已正常启动

> react-native-module@0.0.1 start /Users/danke77/Projects/react-native/HelloReactNative
> node node_modules/react-native/local-cli/cli.js start

Scanning 581 folders for symlinks in /Users/danke77/Projects/react-native/HelloReactNative/node_modules (17ms)
 ┌────────────────────────────────────────────────────────────────────────────┐
 │  Running packager on port 8081.                                            │
 │                                                                            │
 │  Keep this packager running while developing on any JS projects. Feel      │
 │  free to close this tab and run your own packager instance if you          │
 │  prefer.                                                                   │
 │                                                                            │
 │                                    │
 │                                                                            │
 └────────────────────────────────────────────────────────────────────────────┘
Looking for JS files in
   /Users/danke77/Projects/react-native/HelloReactNative

[2016-10-17 17:06:48] <START> Building Dependency Graph
[2016-10-17 17:06:48] <START> Crawling File System
[Hot Module Replacement] Server listening on /hot

React packager ready.

[2016-10-17 17:06:49] <END>   Crawling File System (966ms)
[2016-10-17 17:06:49] <START> Building in-memory fs for JavaScript
[2016-10-17 17:06:49] <END>   Building in-memory fs for JavaScript (260ms)
[2016-10-17 17:06:49] <START> Building in-memory fs for Assets
[2016-10-17 17:06:50] <END>   Building in-memory fs for Assets (138ms)
[2016-10-17 17:06:50] <START> Building Haste Map
[2016-10-17 17:06:50] <START> Building (deprecated) Asset Map
[2016-10-17 17:06:50] <END>   Building (deprecated) Asset Map (104ms)
[2016-10-17 17:06:50] <END>   Building Haste Map (428ms)
[2016-10-17 17:06:50] <END>   Building Dependency Graph (1825ms)

7. 开发调试

模拟器上可以通过工具栏的 Hardware->Shake Gesture 或快捷键调出开发调试菜单;真机上可以通过摇一摇调出。

8. 发布正式包

React Native 的开发版需要有一个 package server 随时发送更新后的 js bundle 文件。如果要打正式包,需要把 js bundle 文件保存到 iOS 项目的目录下。这样,正式包就不需要 server 支持了,可独立运行。

在根目录下创建 bundle/ 文件夹,执行以下命令将 js bundle 保存到资源目录下

$ react-native bundle --platform ios --dev false --entry-file index.ios.js --bundle-output ./bundle/index.ios.bundle --assets-dest ./bundle

bundle/ 下就会生成 index.ios.bundle 文件及 assets/ 文件夹,后者会放 React Native 中用到的资源如图片等。

然后将生成的 bundle/ 文件夹以 Create folder references 的形式导入到工程里,就可以打正式包了。

Top