[iOS] React Native 移植原生 iOS 平臺項目
(一)前言
今天我們來看一下React Native移植到iOS原生應用,通過本節講解,相信大家對于正在開發的iOS原生項目就可以移植到React Native平臺中來,或者采取原生加RN混合開發模式啦。
剛創建的React Native技術交流5群( 386216878 ),歡迎各位大牛,React Native技術愛好者加入交流!同時博客右側歡迎微信掃描關注訂閱號,移動技術干貨,精彩文章技術推送!
React更多的是作為MVC模式中的V視圖層存在,所以該就非常容易嵌入到非React Native開發的應用中。實際上,該可以和常見的工具進行結合,例如CocoaPods( 詳細請點擊進入了解 ).
(二)準備工作
1.安裝CocoaPods -這個相應大家如果之前做過iOS開發應該都清除的吧。安裝命令:gem install cocoapods
2.Node.js -如果大家已經在Mac平臺已經成功運行過React Native應用,那么該肯定是安裝了(沒安裝,點擊進入了解)。安裝nvm的教程點擊命令,該命令會進行安裝最新的Node.js版本,然后配置好環境變量。最后你可以通過命令node來啟動運行Node.js環境。大家可能也知道,通過nvm,大家可以安裝多個Node.js版本并且很方便的進行切換選擇。
3.間接著,你可以命令切換到你的項目的根目錄,命令運行npm install react-native來進行安裝react-native包依賴。
以上步驟完成之后,在你項目根目錄上面會存在一個React Native包,該命名為node_modules,和.xcodeproj文件平級。
(三)使用CocoaPods進行安裝React Native庫
CocoaPods是iOS/Mac開發中的包管理器,我們需要使用CocoaPods來進行下載React Native。如果你到現在還沒有安裝CocoaPods,那么 請點擊了解安裝向導 ,至于具體怎么樣安裝相信大家看官方向導或者百度一下,就會了。
當你用CocoaPods進行工作的時候,需要往Podfile文件中添加如下的一些代碼信息。如果你還沒有改文件,可以在仙姑的根目錄上面進行創建一下。具體需要添加的信息如下:
# Depending on how your project is organized, your node_modules directory may be
somewhere else; tell CocoaPods where you've installed react-native from npm
pod 'React', :path => './node_modules/react-native', :subspecs => [
'Core',
'RCTImage',
'RCTNetwork',
'RCTText',
'RCTWebSocket',
Add any other subspecs you want to use in your project
]</code></pre>
記住需要添加安裝所有的組件模塊依賴才可以,例如如果你需要使用<Text>元素,但是如果沒有安裝RCTText,那么不行啦。
然后運行命令進行安裝: pod install
(四)創建React Native應用
下面你兩個注意步驟:
1.應用的入口/根JavaScript文件必須包含你的實際React Native應用和其他組件
2.封裝Objective-C代碼,加載你的腳本代碼和創建一個RCTRootView對象來顯示和管理你的React Native組件。
現在我們開始創建啦:
首先創建一個文件夾來存放應用的React代碼,然后新建一個簡單的index.ios.js文件,具體命令如下:
$ mkdir ReactComponent
$ touch ReactComponent/index.ios.js
復制和粘貼如下的代碼到index.ios.js文件中,這是一個最簡單的React Native應用啦;
'use strict';
import React, {
Text,
View
} from 'react-native';
conststyles = React.StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'red'
}
});
class SimpleApp extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>This is a simple application.</Text>
</View>
)
}
}
React.AppRegistry.registerComponent('SimpleApp', () => SimpleApp);</code></pre>
上面代碼中的SimpeApp就是你的模塊名稱,該名稱請記住,后邊需要用到的哦~
(五)往應用中添加容器視圖
現在你需要一個容器視圖來轉載React Native組件,該可以為你應用中任何的UIView。

當然了,為了我們的代碼更加整潔干凈,我們創建一個繼承UIView的ReactView。你點擊YourProject.xcworkspace(具體你本地的項目),然后創建一個新的類ReactView(當然你可以隨你自己喜歡進行命名…)
// ReactView.h
import <UIKit/UIKit.h>
@interface ReactView : UIView
@end</code></pre>
然后在需要管理這個視圖的ViewController中,添加關聯。
// ViewController.m
@interface ViewController ()
@property (weak, nonatomic) IBOutlet ReactView reactView;
@end</code></pre>
[注意].如果你的是Swift應用,就不需要這一步。同時這邊我為了簡化的演示相關效果,已經禁用了AutoLayout了,但是在實際的開發中,那么就需要打開AutoLayout并且設置相關約束。
(六)往容器視圖中添加RCTRootView
前面我們已經做了好多準備工作了,那么現在重點來了,最后在確定一遍,你準備好了沒?現在我們需要來創建RCTRootView來引入React Native應用了。
在ReactView.m文件中,我們首先需要加載index.ios.bundle文件來初始化RCTRootView, index.ios.bundle文件會由React Native Server進行創建并且可以通過React Native服務訪問到。這個我們之后的教程會講解到啦。
NSURL
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios"];
// For production use, this NSURL
could instead point to a pre-bundled file on disk:
//
// NSURL jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
//
// To generate that file, run the curl command and add the output to your main Xcode build target:
//
// curl http://localhost:8081/index.ios.bundle -o main.jsbundle
RCTRootView rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName: @"SimpleApp"
initialProperties:nil
launchOptions:nil];</code></pre>
然后把它添加成ReactView的子視圖
[self addSubview:rootView];
rootView.frame = self.bounds;
(七)Swift應用
如果你的是Swift應用的話,那么需要你在ReactView.swift文件中添加如下代碼:
import UIKit
import React
class ReactView: UIView {
let rootView: RCTRootView = RCTRootView(bundleURL: NSURL(string: "http://localhost:8081/index.ios.bundle?platform=ios"),
moduleName: "SimpleApp", initialProperties: nil, launchOptions: nil)
override func layoutSubviews() {
super.layoutSubviews()
loadReact()
}
func loadReact () {
addSubview(rootView)
rootView.frame = self.bounds
}
}</code></pre>
最后你需要確定一下你的該視圖有沒有添加到視圖容器中或者故事板文件中(StoryBoard)
(八)啟動開發服務器
在項目根目錄中,我們需要開啟React Native開發服務器,具體命令如下:
(JS_DIR=`pwd`/ReactComponent;cd node_modules/react-native; npm run start -- --root $JS_DIR)
以上的命令,可以開啟React Native開發服務,來構建我們的bundle文件。--root選項用來標注React Native應用所在的根目錄。我們當前的例子是ReactComponents目錄,在該文件夾中有一個index.ios.js文件。服務器啟動之后會進行打包出來index.ios.bundle文件,然后讓我們可以通過http://localhost:8081/index.ios.bundle進行訪問。
(九)更新App Transport Security
在iOS9.0開始或者更高版本的系統中,除非特別配置,否則我們的應用是不能通過http訪問localhost主機服務器的。具體解決方案可以查看: http://stackoverflow.com/questions/31254725/transport-security-has-blocked-a-cleartext-http
解決方案:推薦大家在應用的Info.plist文件作如下修改,把localhost本機訪問排查例外項。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
如果大家沒有這樣做,那么可能會遇到Could not connect to development server的錯誤哦
(十)編譯和運行
現在開始編譯和運行你的應用,你會發現你的React Native應用運行在ReactView視圖容器中了,具體截圖如下

注意在模擬器調試中我們可以實現熱加載的(只要修改了JS代碼,模擬器頁面自動刷新的效果,確保在Build Settings->Preprocessor Macros中設置DEBUG=1)
(十一)最后總結
該效果的底層機制為,當RCTRootView被初始化的時候,該會從React Native開發服務器中下載并且解析加載bundle文件。這就意味著我們我們只要實現自己的視圖容器或者ViewController,然后引入RCTRootView,該會進行加載渲染我們的React組件。特別說一下當前官方文檔的官方實例代碼 點擊獲取
今天我們主要學習了一下怎么樣將React Native移植到iOS平臺。大家有問題可以加一下群React Native技術交流5群(386216878).或者底下進行回復一下。
via: http://www.tuicool.com//articles/2A3iQ3m