iOS原生混合RN開發最佳實踐

光強發表於2018-05-16

做過原生iOS開發或者Android開發的同學們肯定也都瞭解Hybrid,有一些Hybrid的開發經驗,目前我們企業開發中運用最廣泛的Hybrid App技術就是原生與H5 hybrid,在早期的時候,可能部分同學也接觸過PhoneGap等hybrid技術,今天我們就簡單來聊下一種比較新的Hybrid技術方案,原生App與ReactNativie Hybrid,如果有同學們對React Native技術不熟悉的同學,可以檢視作者簡書中對React Native基礎的講解:React Native入門到實戰講解

示例Demo地址

image

具體步驟

  • 建立一個iOS原生專案
  • 將iOS原生專案支援pod
  • 調整目前專案工程的資料夾結構
  • 新增RN依賴相關檔案
  • 安裝React Native
  • 修改Podfile檔案,原生安裝React Native依賴庫
  • 在iOS原生頁面填加RN頁面入口
  • 修改RN入口檔案 index.ios.js
  • 執行npm start 執行專案

建立一個iOS原生專案

使用Xcode建立一個空的專案,這個應該不用多說了

image

專案支援pod

這一操作步驟同樣也很簡單,我們只需要執行下面的幾條命令即可,如果對cocoapods 安裝使用不熟悉的同學請參照作者簡書

  • 建立podfile檔案,我們在有xcodeproj檔案的同級目錄下執行下面命令,這時我們的專案檔案中就多了一個Podfile檔案
$ pod init
複製程式碼
  • 執行pod install 命令來安裝pod,同樣,這個命令也是在有xcodeproj同級目錄下,安裝完成後,我們的專案多了一個
$ pod install
複製程式碼

image

image

注意: 這裡對原生iOS不熟悉的同學們需要注意了,當我們使用pod來作為庫管理工具,後面我們開啟專案執行,我們就需要開啟上圖所示的xcworkspace檔案了

調整目前專案工程的資料夾結構

這裡對資料夾做結構調整是為了後期更好的將Android原始專案也使用RN Hybrid,使iOS和Android共享一份React Native框架,共享同一份JS檔案,調整的後的資料夾結構如下

image

新增RN依賴相關檔案

到這裡,我們原生的iOS專案目錄結構已近調整完畢,後面我們需要處理的都是RN相關的內容了,這裡需要建立的檔案有點多,大家可以直接將示例Demo中的這幾個檔案直接拖到自己的專案中,然後在做修改即可

  • 首先我們需要建立package.json檔案
  • 建立index.ios.js檔案
  • 建立index.android.js檔案
  • 建立bundle資料夾,注意這個資料夾是後面我們接入CodePush熱更新時使用的

安裝React Native

安裝React Native這個也很簡單,我們也是簡單的執行下面的命令即可,注意:執行npm 系列的命令,我們都需要在專案根目錄(有package.json檔案的目錄)下執行

$ npm install
複製程式碼

package.json檔案內容如下

{
  "name": "iOSHybridRNDemo",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "prop-types": "^15.6.1",
    "react": "16.0.0",
    "react-native": "0.50.3",
    "react-native-code-push": "^5.2.2",
    "react-native-root-toast": "^1.3.0",
    "react-native-router-flux": "^4.0.0-beta.24",
    "react-native-simple-store": "^1.3.0",
    "react-native-storage": "^0.2.2",
    "react-native-vector-icons": "^4.3.0",
    "react-redux": "^5.0.6",
    "redux": "^3.7.2",
    "redux-actions": "^2.2.1",
    "redux-promise-middleware": "^4.4.1",
    "redux-thunk": "^2.2.0"
  },
  "devDependencies": {
    "babel-jest": "22.4.1",
    "babel-preset-react-native": "4.0.0",
    "jest": "22.4.2",
    "react-test-renderer": "16.0.0"
  },
  "jest": {
    "preset": "react-native"
  }
}

複製程式碼

注意:因為我們專案中使用到了react-native-vector-icons 這個iconFont元件需要依賴原生,所以我們執行完 npm install 之後,我們還需要 再執行一個 react-native link react-native-vector-icons 命令來安裝原生依賴

$ react-native link react-native-vector-icons
複製程式碼

image

當我們執行完npm install 命令之後,我們再開啟專案目錄,發現多了一個 node_modules 資料夾,這個資料夾就是我們安裝的React Native所有的依賴庫

修改Podfile檔案,原生安裝React Native依賴庫

後面我們都是使用Pod來管理原生的依賴庫,安裝React Native依賴庫,我們只需要將下面的Podfile檔案中的內容新增進去,執行 pod install 安裝即可

Podfile檔案

# Uncomment the next line to define a global platform for your project
  platform :ios, '9.0'
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!

target 'iOSHybridRNDemo' do
  
  # Pods for iOSHybridRNDemo

    #***********************************************************************#
   
    # 'node_modules'目錄一般位於根目錄中
    # 但是如果你的結構不同,那你就要根據實際路徑修改下面的`:path`
    pod 'React', :path => '../node_modules/react-native', :subspecs => [
    'Core',
    'RCTText',
    'RCTImage',
    'RCTActionSheet',
    'RCTGeolocation',
    'RCTNetwork',
    'RCTSettings',
    'RCTVibration',
    'BatchedBridge',
    'RCTWebSocket',
    'ART',
    'RCTAnimation',
    'RCTBlob',
    'RCTCameraRoll',
    'RCTPushNotification',
    'RCTLinkingIOS',
    'DevSupport'
    # 在這裡繼續新增你所需要的模組
    ]

    # 如果你的RN版本 >= 0.42.0,請加入下面這行
    pod "yoga", :path => "../node_modules/react-native/ReactCommon/yoga"
    
    #***********************************************************************#

    pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'

end

複製程式碼

注意: #*************************# 中間的內容是我們需要新增的RN依賴庫,後面我們所有pod 相關的命令,我們都需要iOS根目錄(有Podfile檔案的目錄)下執行

  • 執行安裝命令
$ pod install
複製程式碼

image

在iOS原生頁面填加RN頁面入口

現在我就來實現從原生頁面跳RN頁面

  • 使用RN提供一個View檢視程式碼如下
NSURL * jsCodeLocation;
#ifdef DEBUG
    NSString * strUrl = @"http://localhost:8081/index.ios.bundle?platform=ios&dev=true";
    jsCodeLocation = [NSURL URLWithString:strUrl];
#else
    jsCodeLocation = [CodePush bundleURL];
#endif
    
    NSDictionary *params = @{@"componentName":@"MeApp1", @"args":@{@"params":@"這是原生傳遞的引數"}};

    RCTRootView * rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                         moduleName:@"iOSRN"
                                                  initialProperties:params
                                                      launchOptions:nil];
    self.view = rootView;
複製程式碼

修改RN入口檔案 index.ios.js

修改RN頁面的入口檔案,這裡當是iOS入口我們修改index.ios.js檔案,當Android入口,我們修改index.android.js檔案

  • index.ios.js檔案
import React, {Component} from 'react'
import {
  Platform,
  StyleSheet,
  Text,
  View,
  AppRegistry
} from 'react-native';

const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
  android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit App.js
        </Text>
        <Text style={styles.instructions}>
          {instructions}
        </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('iOSHybridRNDemo', () => App)
複製程式碼

執行npm start 執行專案

到這裡,我們一個簡單的原生嵌入RN開發工程就搭建完成了,我們執行下面命令來執行專案,檢視效果

  • 開啟node 服務
$ npm start
複製程式碼
  • 執行效果

image

小福利

  • 作者React Native開源專案OneM地址(按照企業開發標準搭建框架完成開發的):github.com/guangqiang-…:歡迎小夥伴們 star
  • 作者簡書主頁:包含60多篇RN開發相關的技術文章www.jianshu.com/u/023338566… 歡迎小夥伴們:多多關注多多點贊
  • 作者React Native QQ技術交流群:620792950 歡迎小夥伴進群交流學習
  • 友情提示:在開發中有遇到RN相關的技術問題,歡迎小夥伴加入交流群(620792950),在群裡提問、互相交流學習。交流群也定期更新最新的RN學習資料給大家,謝謝大家支援!

相關文章