RN開發過渡 - 在純原生iOS項目中集成React-Native

RN 入門

本文主要記錄了自己在往原生項目中集成React-Native(以下簡稱RN)開發的一些經驗和踩的坑,對這次的經歷做一個備忘錄,同時希望能幫到更多的人。

關于為什么要使用RN開發,本文不做更多的論述。RN的優缺點的論點網上太多了,讀者自行搜索查找、思考、甄別。

目前RN的最新版本是051,本文所有的內容都在該版本上的開發、測試。

我本人使用的是Mac端開發,并只在iOS的項目上做的測試。

好,進入正題。

一、搭建RN開發環境

既然要使用RN開發,最基本的肯定要搭建其開發環境。搭建RN開發環境一共分為:

  • 安裝必要軟件
  • 測試安裝

1. 安裝必需的軟件

Homebrew

Homebrew, Mac系統的包管理器,用于安裝NodeJS和一些其他必需的工具軟件。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

在Max OS X 10.11(El Capitan)版本中,homebrew在安裝軟件時可能會碰到/usr/local目錄不可寫的權限問題。可以使用下面的命令修復:

sudo chown -R `whoami` /usr/local
Node

使用Homebrew來安裝Node.js.

React Native目前需要NodeJS 5.0或更高版本。本文發布時Homebrew默認安裝的是最新版本,一般都滿足要求。

brew install node

安裝完node后建議設置npm鏡像以加速后面的過程(或使用科學上網工具)。注意:不要使用cnpm!cnpm安裝的模塊路徑比較奇怪,packager不能正常識別!

npm config set registry https://registry.npm.taobao.org --global

npm config set disturl https://npm.taobao.org/dist --global
Yarn、React Native的命令行工具(react-native-cli)

Yarn是Facebook提供的替代npm的工具,可以加速node模塊的下載。React Native的命令行工具用于執行創建、初始化、更新項目、運行打包服務(packager)等任務。

npm install -g yarn react-native-cli

安裝完yarn后同理也要設置鏡像源:

yarn config set registry https://registry.npm.taobao.org --global

yarn config set disturl https://npm.taobao.org/dist --global

如果你看到EACCES: permission denied這樣的權限報錯,那么請參照上文的homebrew譯注,修復/usr/local目錄的所有權:

sudo chown -R `whoami` /usr/local

安裝完yarn之后就可以用yarn代替npm了,例如用yarn代替npm install命令,用yarn add 某第三方庫名代替npm install --save 某第三方庫名

Watchman

Watchman是由Facebook提供的監視文件系統變更的工具。安裝此工具可以提高開發時的性能(packager可以快速捕捉文件的變化從而實現實時刷新)。

brew install watchman
Xcode

這個就不多說了,在APPStrore下載即可。最好保證下載Xcode7.0以上。

2.測試

以上軟件安裝好了之后,我們現在可以開始嘗試創建一個RN項目了,測試看是否出現紕漏。
打開Mac的終端工具命令行:

react-native init myFirstRNProject

這里是在mac的根目錄創建一個myFirstRNProject的文件夾。我們的項目所需要的一切文件也會在這個文件夾里面被創建好。這種方式創建的就是最新版本的RN,也就是0.51版本。
如果我們需要進行指定版本的創建的話,可以像下面這樣創建:

react-native init myFirstRNProject --version 0.45

這種方式將會創建0.45版本的RN項目。
創建RN文件夾后,執行:

cd myFirstRNProject

進入到該項目中。

react-native run-ios

啟動項目中的iOS部分。
注意: 啟動之后,Mac會自動開啟一個終端的對話框,這個對話框在項目的開啟期間必須要一直打開著,如果被關閉,整個項目也就被關閉了。
打開項目看到這個樣子:

RN新項目

我們將在 APP.JS文件夾中編寫項目需要的代碼。 如果是049之前的版本,則應該在 index.ios.jsindex.Android.js中分別iOS和安卓的代碼。
如果一切正常,說明項目就是創建成功了。

二、搭建原生項目集成環境

搭建好了開發環境之后,我們能夠隨時創建一個新的項目了。這時候就具備了給原生項目集成RN的環境。

1. 首先創建一個空的文件夾。

這個文件夾將會是集成之后項目文件。假設我給他取名: iOS-RN.

2. 在 iOS-RN 文件夾中,創建一個/ios文件。

這個/ios文件中將存放原生項目中所有的文件。這直接將原生項目中的文件復制一份拷貝過來即可。

3. 安裝JavaScript依賴包: package.js文件

在項目根目錄(和/ios平級)下創建一個名為package.json的空文本文件,然后填入以下內容:

{
  "name": "MyReactNativeApp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "react": "16.0.0-alpha.6",    //  指定了React 版本
    "react-native": "0.51"    //這里指定了RN的版本
  }
}

示例中的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@某.某.某版本。如果你使用多個第三方依賴,可能這些第三方各自要求的react版本有所沖突,此時應優先滿足react-native所需要的react版本。其他第三方能用則用,不能用則只能考慮選擇其他庫。

設置完成之后,安裝依賴包:

$ npm install
4. 在原生項目中使用CocoaPod添加RN依賴文件

使用終端cd進入到/ios文件中,安裝CocoaPod依賴包管理系統。(這里推薦使用CocoaPods,如果之前的原生項目中沒有安裝的話,需要自行想辦法安裝一個)。
對于已經安裝了CocoaPod 的項目,我們進入到對應的podfile文件:

$ vim podfile

在podfile文件中添加以下內容:

 # 'node_modules'目錄一般位于根目錄中
  # 但是如果你的結構不同,那你就要根據實際路徑修改下面的`:path`
  pod 'React', :path => '../node_modules/react-native', :subspecs => [
    'Core',
    'CxxBridge', # 如果RN版本 >= 0.45則加入此行
    'DevSupport', # 如果RN版本 >= 0.43,則需要加入此行才能開啟開發者菜單
    'RCTText',
    'RCTNetwork',
    'RCTWebSocket', # 這個模塊是用于調試功能的
    # 在這里繼續添加你所需要的RN模塊
  ]
  # 如果你的RN版本 >= 0.42.0,則加入下面這行。
  pod "yoga", :path => "../node_modules/react-native/ReactCommon/yoga"
 # 這里注意: 如果是0.49以下的RN,則使用下面這條:
 # pod "Yoga", :path => "../node_modules/react-native/ReactCommon/yoga"

   # 如果RN版本 >= 0.45則加入下面三個第三方編譯依賴
  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'GLog', :podspec => '../node_modules/react-native/third-party-podspecs/GLog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'

完了之后,更新Pod。

 $ pod install   

有時候會更新失敗,注意查看失敗的原因,對癥修改即可。
更新成功之后,我們在項目中就可以通過import React使用React提供的庫文件了。在每一個需要用到RN相關內容的界面的原生代碼中,都需要加入這個頭文件。

三、橋接RN和iOS項目中的內容

按照傳統,我打算使用RN寫一個“Heollo world” 的界面,然后在原生的項目中使用這個界面。

1. 創建index.js文件。

在和ios文件夾平級的目錄下(根目錄),使用命令
$ touch index.js
創建index.js文件。這個文件是RN的入口文件,如果是 049之前的RN,那么應該創建index.ios.js文件。

2. 在index.js文件寫入以下代碼:
import React from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';

class FirstView extends React.Component {
  render() {
    var contents = this.props.rootTag;
    return (
      <View style={styles.center}>
        <Text >
          {this.props.content}
        </Text>
      </View>

    );
  }
}

const styles = StyleSheet.create({
  center: {
    marginTop: 50,
    width:120,
    height: 60,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor:"red"
  },
});

// 整體js模塊的名稱
AppRegistry.registerComponent('FirstView', () => FirstView);

具體代碼的意思就是在一個頁面中添加了一個包含“Hello world”文字的 <Text>控件。

3. 編寫原生代碼對接RN

為了簡單起見,我直接在AppDelegate文件中,將window的根視圖設置成RN編寫的“Hello world”界面。
當然,我們同樣可以在其他的原生界面進行跳轉到RN界面。
首先

import  React

然后在 didFinishLaunchingWithOptions 函數中:

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        self.window = UIWindow.init(frame: CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight))
        self.window?.makeKeyAndVisible()

//      如果是 使用真機調試,需要使用電腦的IP地址。
//      let url = URL.init(with: "http://192.168.0.174:8081/index.bundle?platform=ios")   

//     如果是使用Xcode自帶的模擬器,則直接使用本地服務器的端口即可。
        let url = URL.init(with: "http://localhost:8081/index.bundle?platform=ios")
        let rootView = RCTRootView.init(bundleURL: url, moduleName: "FirstView", initialProperties: [ "content":"Hello world"], launchOptions: nil)
        let VC = UIViewController.init()
        VC.view = rootView
        self.window?.rootViewController = VC
        return true
    }

注意: 這里的FirstView 的名稱必須和RN中注冊的名稱一模一樣。不然會無法識別的。
這段代碼的意思就是從RN中加載一個頁面(這個頁面就是我們寫的“Hello world”頁面),然后作為window的根視圖展示。

4. 啟動RN項目

使用mac的終端工具,cd 進入到項目的根目錄,就是上面說的 iOS-RN文件夾,在這里可以看到 index.js文件。
輸入命令行:

$ npm start  

之后,RN項目開始啟動,最后, 終端框中會看到這句提示:Loading dependency graph, done.,說明RN啟動完成。這時候注意,不要關閉這個終端,如果需要使用終端執行其他的命令,可以新建窗口。
這時候所有的RN依賴庫都加載完畢,等待原生項目啟動調用。

5. 啟動原生項目

Xocde中,選擇模擬器,comand+R。

如果一切正常的話,打開模擬器之后,會直接進入到了“Hello world”界面。
下圖:


hello world

以上就是在原生項目中集成RN的全部過程了。當然這個過程的步驟很多,很有可能出現各種各樣的錯誤,這時候需要耐心仔細看錯誤提示。RN的錯誤提示做的還是很成熟的,我自己接入RN以來各種錯誤大部分都是通過其錯誤提示修復的,實在不行,就上各種搜索引擎上去搜索吧。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容