React Native - iOS 原生項目集成 React Native

這里只是純粹的iOS 原生項目集成 React Native, 集成前的準備工作這里不多說了,React Native 開發基礎環境和CocoaPods都需要提前都安裝好。(適用于 React Native 0.44.3以下版本)

一、集成React Native

1.設置項目目錄結構

現在有一個 RNIntegration項目,目錄下創建個 ios 文件夾,然后將根目錄(根目錄指的是RNIntegration目錄下,以此類推)下的其他東西都移到 ios 文件夾中(也可以不創建這文件或者起個其他的名字,這個看個人喜好了),如下圖:

新建 ios 文件夾.png

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中的reactreact-native的版本取決于你的具體需求。一般來說我們推薦使用最新版本。你可以使用npm info reactnpm info react-native來查看當前的最新版本。另外,react-nativereact的版本有嚴格要求,高于或低于某個范圍都不可以。本文無法在這里列出所有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命令,運行結果如下:

npm install.png

這些模塊會被安裝到項目根目錄下的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包含了必須的AppRegistryStyleSheetView以及其他的一些React Native核心庫。如果你想使用React Native的Text庫(即<Text>組件),那就需要添加RCTTextsubspec。同理,Image需要加入RCTImage,等等。

在Terminal(終端)中進入RNIntegration.xcodeproj的同級目錄,執行pod更新命令

pod install

運行效果如下:


運行效果.png

二、原生項目處理

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>
方法一.png
方法二:(允許所有的 http 請求)
<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
方法二.png

三、運行項目

1. 啟動開發服務器

在運行我們的項目之前,我們需要先啟動我們的開發服務器(即Packager,它負責實時監測js文件的變動并實時打包,輸出給客戶端運行)。進入packager的同級目錄下 ,然后命令行啟動服務:

react-native start

或者

npm start

啟動服務后,在 xcode 中 run 該項目。
這兩個命令都可以啟動開發服務器,親測,但不知道有什么區別。

2. 運行iOS項目

運行成功效果如下:


運行效果.png

可以成功看到上面的界面,那就恭喜集成成功了。可以嘗試更改 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.

上面新增的配置中的NSAppTransportSecurityATS配置的根節點,配置了節點表示告訴系統要走自定義的ATS設置。而NSAllowsAritraryLoads節點則是控制是否禁用ATS特性,設置YES就是禁用ATS功能。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,380評論 2 379

推薦閱讀更多精彩內容