????中文介紹
RN
全稱React Native
,是Facebook
公司推出的一款能夠跨平臺開發(fā)的框架鬼廓,其能夠使用js
來達到安卓端
和iOS端
共用一套代碼開發(fā)的目的肿仑。React Native
的核心設(shè)計理念是:即擁有React
的開發(fā)效率,又能擁有Native
的體驗。
版本支持
iOS目前支持7.0以上的版本尤慰,安卓目前支持4.1以上的版本
開發(fā)環(huán)境配置
環(huán)境要求
安裝Homebrew
在終端中輸入下面的命令馏锡,執(zhí)行的速度可能比較慢,請耐心等待其執(zhí)行完成
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
在終端中輸入下面的命令驗證是否安裝成功
brew -v
安裝npm和Node.js
安裝watchMan
該插件用于監(jiān)控bug文件和文件變化割择,并且可以觸發(fā)指定的操作眷篇,在終端中輸入下面的命令就可以了
brew install watchman
安裝Flow
flow是一個JavaScript的靜態(tài)類型檢查器,建議安裝它荔泳,以方便找出代碼中可能存在的類型錯誤蕉饼,在終端輸入下面的代碼,如果提示command not found ,請加上sudo獲得最高權(quán)限玛歌。
brew install flow
React Native安裝
在終端輸入
npm install -g react-native-cli
到這里React Native的環(huán)境就已經(jīng)全部配置好了
創(chuàng)建React Native 項目
在終端中輸入下面命令
react-native init 項目名稱
如果速度較慢昧港,可以將npm倉庫源替換為國內(nèi)鏡像:
npm config set registry https://registry.npm.taobao.org
npm config set disturl https://npm.taobao.org/dist
默認生成了三個文件夾,android和iOS為兩個平臺的原生項目支子,index.android.js和index.ios.js為android和iOS平臺下的兩個空殼應(yīng)用文件创肥,我們的代碼一般就寫在這兩個文件內(nèi),客戶端那邊不用重新run就可以看到效果值朋,node_modules文件夾主要是存放框架資源叹侄。
對index.ios.js文件的編寫軟件以及提示插件的安裝
我們采用的是WebStorm來對js文件來進行編寫,由于直接編寫并沒有代碼提示,所以這里要安裝一個插件,下載地址,下載完成后file -> import settings -> ReactNative.jar ,完成之后就可以像Xcode那樣能夠自動提示了.
在現(xiàn)有項目中集成RN
官方推薦的方式是利用CocoaPods
把React Native
組件植入到iOS應(yīng)用中有如下幾個主要步驟:
1.首先當(dāng)然要了解你要植入的React Native
組件
2.創(chuàng)建一個Podfile
,在其中以subspec
的形式填寫所有你要植入的React Native
的組件昨登。
3.創(chuàng)建js
文件趾代,編寫React Native
組件的js代碼
4.添加一個事件處理函數(shù),用于創(chuàng)建一個RCTRootView
丰辣。這個RCTRootView
正是用來承載你的React Native 組件的撒强,而且它必須對應(yīng)你在index.ios.js
中使用AppRegistry
注冊的模塊名字。
5.啟動React Native
的Packager
服務(wù)笙什,運行應(yīng)用
6.根據(jù)需要添加更多的React Native 組件
準備工作
首先確定你的Mac里有沒有安裝下面的兩個環(huán)境:
1.react-native
2.CocoaPods
直接在終端敲下面的兩個命令飘哨,就能看看你有沒有裝咯
1.react-native -v
2.pod --version
從無到有
如果你是一個小白,那么我們就從頭開始吧
1.首先打開我們的Xcode創(chuàng)建一個項目琐凭,用終端cd到你剛創(chuàng)建好的項目文件夾中
2.用終端執(zhí)行pod init 然后再執(zhí)行 pod install
3.在你的項目文件夾里創(chuàng)建一個文件夾來管理RN芽隆,習(xí)慣用命令了,直接終端
mkdir RNUtil
cd RNUtil
4.創(chuàng)建一個package.json的文件
touch package.json
5.在這個文件夾下執(zhí)行npm install
6.等安裝成功后淘正,創(chuàng)建index.ios.js文件摆马,我們就可以開始我們的混編之旅了
touch index.ios.js
Podfile
# Uncomment the next line to define a global platform for your project
platform :ios, ‘8.0’
inhibit_all_warnings!
target 'RNBridgeSwift' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for RNBridgeSwift
# react_path 是你react-native文件夾路徑。
react_path = './RNUtil/node_modules/react-native'
yoga_path = File.join(react_path, 'ReactCommon/yoga')
pod 'React', :path => react_path, :subspecs => [
'Core',
'RCTText',
'RCTImage',
'RCTWebSocket', # needed for debugging
'RCTNetwork'
]
pod 'Yoga', :path => yoga_path
end
Package.json
{
"name": "RNBridgeSwift",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"dependencies": {
"react": "15.4.2",
"react-native": "0.42.3"
}
}
Demo
環(huán)境搭建好了后鸿吆,我們就開始搞個小demo玩玩
首先在準備當(dāng)做原生的頁面的Controller里導(dǎo)入React
import React
寫點啥好呢囤采,就隨便寫個按鈕加倆Label可以實現(xiàn)頁面跳轉(zhuǎn)和傳值吧
重點來了哦,在按鈕的點擊方法里寫上下面的代碼
let localJSPath = URL.init(string:"http://localhost:8081/index.ios.bundle?platform=ios")
let params:[String:Array<Dictionary<String, String>>] = [
"scores" : [
["name":"Alex","value":"42"],
["name":"Joel","value":"10"],
]
]
let rootView : RCTRootView = RCTRootView(bundleURL: localJSPath, moduleName: "RNTestViewModule", initialProperties: params, launchOptions: nil)
對了惩淳,還要創(chuàng)建一個承載js頁面的Controller
在這個Controller的viewWillAppear方法里注冊兩個通知:
NotificationCenter.default.addObserver(self, selector: #selector(RNManagerViewController.backPreviousVC(_:)), name: NSNotification.Name.init(rawValue: "NotificatioinBack"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(RNManagerViewController.backPreviousVC(_:)), name: NSNotification.Name.init(rawValue: "NotificatioinNext"), object: nil)
創(chuàng)建一個類目來詮釋通知:
extension RNManagerViewController {
func backPreviousVC(_ notification: Notification) {
print("current Thread %@",Thread.current)
DispatchQueue.main.async {
if (self.backBlock != nil) {
self.backBlock!(notification.object ?? "");
}
if let navigationVC: UINavigationController = self.navigationController, navigationVC.viewControllers.count > 1 {
navigationVC.popViewController(animated: true)
} else {
self.dismiss(animated: true, completion: nil)
}
}
}
func nextHandle(_ notification: Notification) {
print("current Thread %@",Thread.current)
DispatchQueue.main.async {
if (self.backBlock != nil) {
self.backBlock!(notification.object ?? "");
}
}
}
}
重點來了蕉毯,引入OC的橋接文件乓搬,使RN可以實現(xiàn)OC的方法。
RCT_EXPORT_MODULE(swift);
RCT_EXPORT_METHOD(transportMessage:(id)message){
NSLog(@"transportMessage:\n %@",message);
if ([message isKindOfClass:[NSDictionary class]]) {
NSString *method = [message objectForKey:@"method"];
BOOL isNext = method ? ([method isEqualToString:@"push"] || [method isEqualToString:@"present"]) : NO ;
if (isNext) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"NotificatioinNext" object:message userInfo:nil];
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:@"NotificatioinBack" object:message userInfo:nil];
}
}
}
//RN傳參數(shù)調(diào)用原生OC,并且返回數(shù)據(jù)給RN 通過CallBack
RCT_EXPORT_METHOD(RNInvokeOCCallBack:(NSDictionary *)dictionary callback:(RCTResponseSenderBlock)callback){
NSLog(@"接收到RN傳過來的數(shù)據(jù)為:%@",dictionary);
NSArray *events = @[
@{
@"name" : @"王壘",
@"value": @"111"
},
@{
@"name" : @"King",
@"value": @"99"
}
];
callback(@[[NSNull null], events]);
}
效果圖如下:
總結(jié)
如果你有需要請點下面的按鈕前往Clone代虾。
Clone
git clone https://github.com/KingComeFromChina/RNBridgeSwift.git