1. 程式人生 > >React Native整合到IOS原生專案

React Native整合到IOS原生專案

這裡預設電腦上已經安裝了cocoapods和React-Native,如果沒有RN開發環境,可以點選這裡按照步驟配置。

0、新建專案

首先,先使用xcode新建一個專案,然後在專案的根目錄下新建一個資料夾,用於存放RN的元件庫還有其他一些檔案。這裡假設新建一個名為 RNComponent 的資料夾。目錄結構為:

示圖

1、新建RN配置檔案

準備妥當以後,我們在 RNComponent 這個資料夾裡就可以放置所有RN相關的檔案。新建一個使用者初始化RN的配置檔案,是Json檔案。命名為 package.json

示圖

內容為:

{
  "name": "RNApp",
  "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-native": "0.44.0", "react-native-deprecated-custom-components": "^0.1.0", "react-native-tab-navigator": "^0.3.3" } }

上述程式碼裡的配置資訊已經足夠現在整合專案使用,如果需要了解其它配置資訊的話,可以參考下方:

  • name 是指RN專案的名字,這個和原生專案的名字保持一致即可
  • version 是指專案版本號
  • description 專案的描述
  • author 開發者個人資訊
  • private 當設定為true時,npm不會發布這個package
  • dependencies 指需要哪些依賴元件,並且指明版本號,這樣使用者安裝時,會自動安裝這些依賴元件
  • devDependencies 是指開發或測試的依賴元件,正式打包的時候不會打包到最終的生產包中
  • scripts 定義npm指令碼命令,key值表示命令名,value值表示命令對應的指令碼或者指令碼路徑
  • main 工程生成的package主入口點,當在 node 中呼叫 require(‘{module name}’) 時會 require 到這個檔案
  • repostitory 如果我們這個工程是開源的,這個欄位用來指明工程的倉庫 URL 地址以及版本控制系統的型別,這可以方便其他開發者貢獻程式碼
  • bugs 使用者可以提交bugs的 URL 或者郵件地址

文章結尾放了一些 package.json 的擴充套件內容,感興趣的可以看看。

2、安裝RN

編輯好 package.json 以後,我們來安裝RN。這裡需要確定當前目錄是否為剛才新建的目錄,並且確定 package.json 存在,然後,輸入安裝RN,在終端輸入命令 npm install

示圖

當出現下圖,就說明安裝成功,並且目錄裡多了一個 node_modules 資料夾。如圖:

示圖

示圖

3、設定podfile檔案

安裝完畢以後,我們切換到xcode專案根目錄中,然後再終端輸入 pod init 命令,來生成podfile檔案。如圖:

示圖

示圖

4、使用pod管理依賴元件

生成 podfile 檔案以後,直接編輯,編輯資訊如下:

pod 'Yoga',  :path => './RNComponent/node_modules/react-native/ReactCommon/yoga'
  pod 'React', :path => ‘./RNComponent/node_modules/react-native/', :subspecs => [
 'Core',
  'ART',
  'RCTActionSheet',
  'RCTAdSupport',
  'RCTGeolocation',
  'RCTImage',
  'RCTNetwork',
  'RCTPushNotification',
  'RCTSettings',
  'RCTText',
  'RCTVibration',
  'RCTWebSocket',
  'RCTLinkingIOS']

這裡把所有元件全部做了依賴管理,所以在開發中,就需要根據實際需求來做對應的依賴。如果路徑沒有指定正確,就會報錯,具體點選這裡參考。

編輯好以後,直接在終端輸入 pod install 命令,安裝依賴。出現下圖時,就說明安裝成功:

示圖

此時目錄結構為:

示圖

5、新建RN專案js檔案入口

接下來需要在 RNComponent 資料夾中新建RN的js入口檔案 index.ios.js ,這裡直接複製RN初始化時的檔案,內容如下:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  AppRegistry,  //註冊
  StyleSheet,   //樣式
  Text,         //文字元件
  View,          //檢視元件
  Image
} from 'react-native';

export default class RNApp extends Component {
    render() {
        return (
            <View style={styles.container}>
              <Text style={styles.welcome}>
                nethanhan
              </Text>
              <Text style={styles.instructions}>
                To get started, edit index.ios.js
              </Text>
              <Text style={styles.instructions}>
                Press Cmd+R to reload,{'\n'}
                Cmd+D or shake for dev menu
              </Text>

            </View>
        );
    }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});
//注意這裡的名字需要和專案名字一致
AppRegistry.registerComponent('RNApp', () => RNApp);

6、整合測試

完成所有工作以後,我們開啟xcode專案,然後建立一個按鈕,用於跳轉到另外一個控制器,然後這個控制器直接把RN介面當成自己的view來展示。如圖:

示圖

RN模組的類是 RCTRootView ,例項化時需要傳入相應的引數:

示圖

然後在專案的plist檔案中新增允許http連線宣告,程式碼如下:

<key>NSAppTransportSecurity</key>
  <dict>
    <key>NSExceptionDomains</key>
    <dict>
      <key>localhost</key>
      <dict>
       <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
       <true/>
      </dict>
    </dict>
  </dict>

接下來在終端中切換到剛才的 RNCompoent 目錄下,執行 react-native start 命令,如圖:

示圖

最後執行xcode專案,點選按鈕,會跳轉到RN介面的控制器裡,就會出現RN的介面(第一次執行會慢一些),如圖:

示圖

OK! 至此,我們已經成功的把RN整合到IOS原生專案中。 如果有什麼疑問,隨時歡迎評論!

7、package.json擴充套件

我們在上方 package.json 中只配置了一些常用的資訊,還有一些其它的說明,可以點選這裡查閱。因為是屬於npm的知識點,所以在這裡放上一個真實專案的 package.json 的內容:

{
  "name": "module-name",
  "version": "10.3.1",
  "description": "An example module to illustrate the usage of a package.json",
  "author": "Your Name <[email protected]>",
  "contributors": [{
  "name": "Foo Bar",
  "email": "[email protected]"
}],
  "bin": {
  "module-name": "./bin/module-name"
},
  "scripts": {
    "test": "vows --spec --isolate",
    "start": "node index.js",
    "predeploy": "echo im about to deploy",
    "postdeploy": "echo ive deployed",
    "prepublish": "coffee --bare --compile --output lib/foo src/foo/*.coffee"
  },
  "main": "lib/foo.js",
  "repository": {
  "type": "git",
  "url": "https://github.com/nodejitsu/browsenpm.org"
},
  "bugs": {
  "url": "https://github.com/nodejitsu/browsenpm.org/issues"
},
  "keywords": [
  "nodejitsu",
  "example",
  "browsenpm"
],
  "dependencies": {
    "primus": "*",
    "async": "~0.8.0",
    "express": "4.2.x",
    "winston": "git://github.com/flatiron/winston#master",
    "bigpipe": "bigpipe/pagelet",
    "plates": "https://github.com/flatiron/plates/tarball/master"
  },
  "devDependencies": {
    "vows": "^0.7.0",
    "assume": "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0",
    "pre-commit": "*"
  },
  "preferGlobal": true,
  "private": true,
  "publishConfig": {
  "registry": "https://your-private-hosted-npm.registry.nodejitsu.com"
},
  "subdomain": "foobar",
  "analyze": true,
  "license": "MIT"
}