iOS原生混合RN開發詳解 做過原生iOS開發或者Android開發的同學們肯定也都瞭解Hybrid,有一些Hybrid的開發經驗,目前我們企業開發中運用最廣泛的Hybrid App技術就是原生與H5 hybrid,在早期的時候,可能部分同學也接觸過PhoneGap等hybrid技術,今天我們就簡單 ...
iOS原生混合RN開發詳解
做過原生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地址(按照企業開發標準搭建框架完成開發的):https://github.com/guangqiang-liu/OneM:歡迎小伙伴們 star
- 作者簡書主頁:包含60多篇RN開發相關的技術文章http://www.jianshu.com/u/023338566ca5歡迎小伙伴們:多多關註,多多點贊
- 作者React Native QQ技術交流群:620792950 歡迎小伙伴進群交流學習
- 友情提示:在開發中有遇到RN相關的技術問題,歡迎小伙伴加入交流群(620792950),在群里提問、互相交流學習。交流群也定期更新最新的RN學習資料給大家,謝謝大家支持!