iOS 原生混合RN開發(fā)最佳實(shí)踐

iOS原生混合RN開發(fā)詳解

做過原生iOS開發(fā)或者Android開發(fā)的同學(xué)們肯定也都了解Hybrid,有一些Hybrid的開發(fā)經(jīng)驗(yàn),目前我們企業(yè)開發(fā)中運(yùn)用最廣泛的Hybrid App技術(shù)就是原生與H5 hybrid,在早期的時(shí)候,可能部分同學(xué)也接觸過PhoneGap等hybrid技術(shù),今天我們就簡單來聊下一種比較新的Hybrid技術(shù)方案,原生App與ReactNativie Hybrid,如果有同學(xué)們對React Native技術(shù)不熟悉的同學(xué),可以查看作者簡書中對React Native基礎(chǔ)的講解:React Native入門到實(shí)戰(zhàn)講解

示例Demo地址

image

具體步驟

  • 創(chuàng)建一個(gè)iOS原生項(xiàng)目
  • 將iOS原生項(xiàng)目支持pod
  • 調(diào)整目前項(xiàng)目工程的文件夾結(jié)構(gòu)
  • 添加RN依賴相關(guān)文件
  • 安裝React Native
  • 修改Podfile文件,原生安裝React Native依賴庫
  • 在iOS原生頁面填加RN頁面入口
  • 修改RN入口文件 index.ios.js
  • 執(zhí)行npm start 運(yùn)行項(xiàng)目

創(chuàng)建一個(gè)iOS原生項(xiàng)目

使用Xcode創(chuàng)建一個(gè)空的項(xiàng)目,這個(gè)應(yīng)該不用多說了

image

項(xiàng)目支持pod

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

  • 創(chuàng)建podfile文件,我們在有xcodeproj文件的同級目錄下執(zhí)行下面命令,這時(shí)我們的項(xiàng)目文件中就多了一個(gè)Podfile文件
$ pod init
  • 執(zhí)行pod install 命令來安裝pod,同樣,這個(gè)命令也是在有xcodeproj同級目錄下,安裝完成后,我們的項(xiàng)目多了一個(gè)
$ pod install
image
image

注意: 這里對原生iOS不熟悉的同學(xué)們需要注意了,當(dāng)我們使用pod來作為庫管理工具,后面我們打開項(xiàng)目運(yùn)行,我們就需要打開上圖所示的xcworkspace文件了

調(diào)整目前項(xiàng)目工程的文件夾結(jié)構(gòu)

這里對文件夾做結(jié)構(gòu)調(diào)整是為了后期更好的將Android原始項(xiàng)目也使用RN Hybrid,使iOS和Android共享一份React Native框架,共享同一份JS文件,調(diào)整的后的文件夾結(jié)構(gòu)如下

image

添加RN依賴相關(guān)文件

到這里,我們原生的iOS項(xiàng)目目錄結(jié)構(gòu)已近調(diào)整完畢,后面我們需要處理的都是RN相關(guān)的內(nèi)容了,這里需要?jiǎng)?chuàng)建的文件有點(diǎn)多,大家可以直接將示例Demo中的這幾個(gè)文件直接拖到自己的項(xiàng)目中,然后在做修改即可

  • 首先我們需要?jiǎng)?chuàng)建package.json文件
  • 創(chuàng)建index.ios.js文件
  • 創(chuàng)建index.android.js文件
  • 創(chuàng)建bundle文件夾,注意這個(gè)文件夾是后面我們接入CodePush熱更新時(shí)使用的

安裝React Native

安裝React Native這個(gè)也很簡單,我們也是簡單的執(zhí)行下面的命令即可,注意:執(zhí)行npm 系列的命令,我們都需要在項(xiàng)目根目錄(有package.json文件的目錄)下執(zhí)行

$ npm install

package.json文件內(nèi)容如下

{
  "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"
  }
}

注意:因?yàn)槲覀冺?xiàng)目中使用到了react-native-vector-icons 這個(gè)iconFont組件需要依賴原生,所以我們執(zhí)行完 npm install 之后,我們還需要 再執(zhí)行一個(gè) react-native link react-native-vector-icons 命令來安裝原生依賴

$ react-native link react-native-vector-icons
image

當(dāng)我們執(zhí)行完npm install 命令之后,我們再打開項(xiàng)目目錄,發(fā)現(xiàn)多了一個(gè) node_modules 文件夾,這個(gè)文件夾就是我們安裝的React Native所有的依賴庫

修改Podfile文件,原生安裝React Native依賴庫

后面我們都是使用Pod來管理原生的依賴庫,安裝React Native依賴庫,我們只需要將下面的Podfile文件中的內(nèi)容添加進(jìn)去,執(zhí)行 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'目錄一般位于根目錄中
    # 但是如果你的結(jié)構(gòu)不同,那你就要根據(jù)實(shí)際路徑修改下面的`: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'
    # 在這里繼續(xù)添加你所需要的模塊
    ]

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

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

end

注意: #*************************# 中間的內(nèi)容是我們需要添加的RN依賴庫,后面我們所有pod 相關(guān)的命令,我們都需要iOS根目錄(有Podfile文件的目錄)下執(zhí)行

  • 執(zhí)行安裝命令
$ pod install
image

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

現(xiàn)在我就來實(shí)現(xiàn)從原生頁面跳RN頁面

  • 使用RN提供一個(gè)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":@"這是原生傳遞的參數(shù)"}};

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

修改RN入口文件 index.ios.js

修改RN頁面的入口文件,這里當(dāng)是iOS入口我們修改index.ios.js文件,當(dāng)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)

執(zhí)行npm start 運(yùn)行項(xiàng)目

到這里,我們一個(gè)簡單的原生嵌入RN開發(fā)工程就搭建完成了,我們執(zhí)行下面命令來運(yùn)行項(xiàng)目,查看效果

  • 開啟node 服務(wù)
$ npm start
  • 運(yùn)行效果
image

福利時(shí)間

  • 作者React Native開源項(xiàng)目OneM地址(按照企業(yè)開發(fā)標(biāo)準(zhǔn)搭建框架完成開發(fā)的):https://github.com/guangqiang-liu/OneM:歡迎小伙伴們 star
  • 作者簡書主頁:包含60多篇RN開發(fā)相關(guān)的技術(shù)文章http://www.lxweimin.com/u/023338566ca5 歡迎小伙伴們:多多關(guān)注多多點(diǎn)贊
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,802評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內(nèi)容

  • 本文主要記錄了自己在往原生項(xiàng)目中集成React-Native(以下簡稱RN)開發(fā)的一些經(jīng)驗(yàn)和踩的坑,對這次的經(jīng)歷做...
    BennyLoo閱讀 6,045評論 13 26
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,604評論 25 707
  • 用到的組件 1、通過CocoaPods安裝 2、第三方類庫安裝 3、第三方服務(wù) 友盟社會(huì)化分享組件 友盟用戶反饋 ...
    SunnyLeong閱讀 14,634評論 1 180
  • 每一次相聚,定會(huì)是不一樣的人。不同的人在一起,注定會(huì)有不一樣的結(jié)局。而這些人若能發(fā)揮團(tuán)隊(duì)協(xié)作力,定會(huì)很美好! 5月...
    小笨魚王月閱讀 275評論 1 0
  • 遠(yuǎn)處綿綿起伏的山脈, 似人間仙境; 近處沙沙作響的白楊, 卻擾人清悠; 君在云里霧里飄搖, 我卻尋尋覓覓未果! 3...
    夢一場921閱讀 293評論 0 3