這里只是純粹的iOS 原生項目集成 React Native, 集成前的準備工作這里不多說了,React Native 開發基礎環境和CocoaPods都需要提前都安裝好。(適用于 React Native 0.44.3以下版本)
一、集成React Native
1.設置項目目錄結構
現在有一個 RNIntegration項目,目錄下創建個 ios 文件夾,然后將根目錄(根目錄指的是RNIntegration目錄下,以此類推)下的其他東西都移到 ios 文件夾中(也可以不創建這文件或者起個其他的名字,這個看個人喜好了),如下圖:
2.創建配置文件
在根目錄下創建package.json
文件,文件內容如下:
{
"name": "RNIntegration",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"dependencies": {
"react": "16.0.0-alpha.6",
"react-native": "0.44.3"
}
}
示例中的
version
字段沒有太大意義(除非你要把你的項目發布到npm倉庫)。scripts
中是用于啟動packager服務的命令。dependencies
中的react
和react-native
的版本取決于你的具體需求。一般來說我們推薦使用最新版本。你可以使用npm info react
和npm info react-native
來查看當前的最新版本。另外,react-native
對react
的版本有嚴格要求,高于或低于某個范圍都不可以。本文無法在這里列出所有react native
和對應的react
版本要求,只能提醒讀者先嘗試執行npm install
,然后注意觀察安裝過程中的報錯信息,例如require react@某.某.某版本, but none was installed
,然后根據這樣的提示,執行npm i -S react@某.某.某版本
。如果你使用多個第三方依賴,可能這些第三方各自要求的react
版本有所沖突,此時應優先滿足react-native
所需要的react
版本。其他第三方能用則用,不能用則只能考慮選擇其他庫。
3.安裝React Native依賴包
接下來我們使用npm(node包管理器,Node package manager)來安裝React和React Native模塊。在Terminal(終端)中進入到根目錄(即包含有package.json文件的目錄)執行npm install
命令,運行結果如下:
這些模塊會被安裝到項目根目錄下的
node_modules/
目錄中(所有通過npm install
命令安裝的模塊都會放在這個目錄中。這個目錄我們原則上不復制、不移動、不修改、不上傳,隨用隨裝)。
4.創建 index.ios.js(js文件入口)
在根目錄文件夾里創建index.ios.js文件,作為js文件入口。
index.ios.js文件內容如下:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
//這里的類名要改成你自己項目的類名
class RNIntegration extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</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('RNIntegration', () => RNIntegration);
5. Cocoapods集成React Native
若原項目無使用Cocoapods,則在根目錄下創建Podfile。(有則直接添加pod相關代碼)
Podfile文件內容為(需確保路徑對):
platform :ios, "8.0"
# target的名字一般與你的項目名字相同
target 'RNIntegration' do
# 如果你的結構不同,那你就要根據實際路徑修改下面的`:path`
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'DevSupport',
'RCTText',
'RCTNetwork',
'RCTWebSocket',
'RCTImage',
...... #這里可以添加你需要的框架
]
# 如果你的RN版本 >= 0.42.0,則加入下面這行
pod "Yoga", :path => "../node_modules/react-native/ReactCommon/yoga"
end
在你開始把React Native集成到你的應用中之前,首先要決定具體整合的是React Native框架中的哪些部分。而這就是subspec
要做的工作。在創建Podfile文件的時候,需要指定具體安裝哪些React Native的依賴庫。所指定的每一個庫就稱為一個subspec
。
可用的subspec
都列在node_modules/react-native/React.podspec
中,基本都是按其功能命名的。一般來說你首先需要添加Core
,這一subspec
包含了必須的AppRegistry
、StyleSheet
、View
以及其他的一些React Native核心庫。如果你想使用React Native的Text
庫(即<Text>
組件),那就需要添加RCTText
的subspec
。同理,Image
需要加入RCTImage
,等等。
在Terminal(終端)中進入RNIntegration.xcodeproj的同級目錄,執行pod更新命令
pod install
運行效果如下:
二、原生項目處理
1. 向對應ViewController 添加RCTRootView
在AppDelegate.m
文件中導入以下 .h 文件:
#import "RCTBundleURLProvider.h"
#import "RCTRootView.h"
在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
中添加以下代碼:
NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios"];
RCTRootView *rootView =
[[RCTRootView alloc] initWithBundleURL : jsCodeLocation
moduleName : @"RNIntegration"http://要改成當前項目的名字
initialProperties : nil
launchOptions : nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
2. iOS項目更新App Transport Security
在iOS 9以上的系統中,除非明確指明,否則應用無法通過http協議連接到localhost主機。 我們建議你在Info.plist文件中將localhost
列為App Transport Security的例外。 如果不這樣做,在嘗試通過http連接到服務器時,會遭遇這個錯誤 - Could not connect to development server.
原因是ATS限制使用HTTP, 數據請求盡量通過HTTPS加密傳輸,
方法一:(只允許 localhost 請求)
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
方法二:(允許所有的 http 請求)
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
三、運行項目
1. 啟動開發服務器
在運行我們的項目之前,我們需要先啟動我們的開發服務器(即Packager,它負責實時監測js文件的變動并實時打包,輸出給客戶端運行)。進入packager的同級目錄下 ,然后命令行啟動服務:
react-native start
或者
npm start
啟動服務后,在 xcode 中 run 該項目。
這兩個命令都可以啟動開發服務器,親測,但不知道有什么區別。
2. 運行iOS項目
運行成功效果如下:
可以成功看到上面的界面,那就恭喜集成成功了。可以嘗試更改 index.ios.js 中的內容,然后在模擬器中是用快捷鍵cmd+R
來 reload 當前界面。
附錄
ATS
ATS限制使用HTTP, 數據請求盡量通過HTTPS加密傳輸,且HTTPS的請求也要滿足以下規定:
1.傳輸層協議(TLS)至少為1.2版本
2.連接的加密方式要提供Forward Secrecy,支持如下加密算法詳見蘋果官方文檔
3.證書至少要使用一個SHA256的指紋與任一個2048位或者更高位的RSA密鑰,或者是256位或者更高位的ECC密鑰。如果不符合其中一項,請求將被中斷并返回nil.
上面新增的配置中的NSAppTransportSecurity是ATS配置的根節點,配置了節點表示告訴系統要走自定義的ATS設置。而NSAllowsAritraryLoads節點則是控制是否禁用ATS特性,設置YES就是禁用ATS功能。