React Native 導入原生Xcode項目總結與記錄


 

React Native 導入原生Xcode項目總結與記錄

背景
最近學習RN、根據中文網上的教程導入原生Xcode項目過程中遇到很多坑、所以記錄一下自己集成的過程,順便重新梳理一下思路,方便日后使用,如果能幫到同樣學習RN的新手,那就更好了😀

說明:本記錄依據RN中文網,並根據自己實踐整理而成

1.集成RN到iOS應用步驟

大體步驟如下:

  • 簡單了解和學習要導入的RN組件
  • 創建一個Podfile 通過cocoaPods來導入我們需要的植入的RN組件
  • 創建js文件,編寫RN組件的源代碼
  • 添加一個事件處理函數、用於創極愛一個RCTRootView。這個view就是RN的根視圖,用來承載你的RN組件,它必須在你對應的index.ios.js 中使用APPRegistry注冊的模塊名字
  • 啟動RN的Packager服務,運行應用
  • 根據需要添加更多的RN組件
  • 調試程序
  • 准備部署發布(比如可以利用react-native-xcode.sh腳本)
  • 發布

2.開發環境准備

  1. 基礎環境 首先要安裝React Native在iOS平台上所需的一切依賴軟件(如npm,node等) --- RN開發環境搭建傳送門
  2. CocoaPods環境 cocoaPods是針對iOS和Mac開發的包管理工具,做過開發的並使用它管理過三方庫的一點都不陌生,同樣RN框架的代碼也通過它來下載並添加到項目中。 ---- cocoaPods安裝使用教程傳送門

3.示例APP

示例程序采用2048小游戲,下面是尚未植入RN時候的頁面

Snip20170405_1.png

4.依賴包

React Native的植入過程中需要React 和 React Native兩個node依賴包。

package.json

具體的依賴包會記錄在 package.json 文件中,如果項目中沒有的自己創建吧(推薦使用 Sublime Text)

對於一個典型的RN項目來說,一般package.jsonindex.ios.js等文件會放在項目的根目錄下。而iOS相關的源代碼會放在一個名為 ios/ 的子目錄中,這里同樣放着Xcode項目文件(.xcodeproj

下面是我的package.json示例

示例中的version字段沒有太大意義(除非你要把你的項目發布到npm倉庫)。scripts中是用於啟動packager服務的命令。dependencies中的react和react-native的版本取決於你的具體需求。一般來說我們推薦使用最新版本。你可以使用npm info reactnpm info react-native來查看當前的最新版本。另外,react-native對react的版本有嚴格要求,高於或低於某個范圍都不可以。本文無法在這里列出所有react native和對應的react版本要求,只能提醒讀者先嘗試執行npm install,然后注意觀察安裝過程中的報錯信息,例如require react@某.某.某版本, but none was installed,然后根據這樣的提示,執行npm i -S react@某.某.某版本

{
  "name": "NumberTileGame",
  "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"
  }
}

我集成時候的最新版為15.4.2 和0.42,但是這個更新很快,你做的時候可能已經是新版了,

5.安裝依賴包

使用npm(node包管理器,Node package manager)來安裝React和React Native模塊。這些模塊會被安裝到項目根目錄下的node_modules/目錄中。 在包含有package.json文件的目錄(一般也就是項目根目錄)中運行下列命令來安裝:
$ npm install

6.通過Pods導入React Native框架

React Native框架整體是作為node模塊安裝到項目中的。下一步我們需要在CocoaPods的Podfile中指定我們所需要使用的組件。

6.1 Subspecs

在你開始把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庫(即組件),那就需要添加RCTText的subspec。同理,Image需要加入RCTImage,等等。

6.2 Podfile

在React和React Native模塊成功安裝到node_modules目錄之后,你就可以開始創建Podfile以便選擇所需的組件安裝到應用中。

創建Podfile的最簡單的方式就是在iOS原生代碼所在的目錄中使用CocoaPods的init命令:(在Xcode項目目錄中)
$ pod init 或者 $ touch Podfile

Podfile會創建在執行命令的目錄中。你需要調整其內容以滿足你的植入需求。下面是我調整后的Podfile的內容【這塊有坑,出現和解決】:

# target的名字一般與你的項目名字相同
platform :ios, '9.0'
target 'NumberTileGame' do

  # 'node_modules'目錄一般位於根目錄中
  # 但是如果你的結構不同,那你就要根據實際路徑修改下面的`:path`
  pod 'React', :path => '../node_modules/react-native', :subspecs => [
    'Core',
    'RCTText',
    'RCTNetwork',
    'RCTWebSocket', # 這個模塊是用於調試功能的
    # 在這里繼續添加你所需要的模塊
  ]
  # 如果你的RN版本 >= 0.42.0,請加入下面這行
  pod "Yoga", :path => "../node_modules/react-native/ReactCommon/yoga"

end

6.3 安裝Pod

Podfile寫完了,現在就可以安裝React Native的Pod包了:
$ pod install

然后你應該可以看到類似下面的輸出(譯注:同樣由於眾所周知的網絡原因,pod install的過程在國內非常不順利,請自行配備穩定的翻牆工具,或是嘗試一些鏡像源):

Analyzing dependencies
Fetching podspec for `React` from `../node_modules/react-native`
Downloading dependencies
Installing React (0.26.0)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There are 3 dependencies from the Podfile and 1 total pod installed.

7. 代碼集成

現在我們已經准備好了所有依賴,可以開始着手修改原生代碼來把React Native真正植入到應用中了。在我們的2048示例中,首先嘗試添加一個顯示有"High Score"(得分排行榜)的React Native頁面。

React Native組件
我們首先要寫的是"High Score"(得分排行榜)的JavaScript端的代碼。

創建一個index.ios.js文件

首先創建一個空的index.ios.js文件。一般來說我們把它放置在項目根目錄下。

index.ios.js是React Native應用在iOS上的入口文件。而且它是不可或缺的!它可以是個很簡單的文件,簡單到可以只包含一行require/import導入語句。本教程中為了簡單示范,把全部的代碼都寫到了index.ios.js里(當然實際開發中我們並不推薦這樣做)。

在項目根目錄執行以下命令創建文件:
$ touch index.ios.js

添加你自己的React Native代碼

在index.ios.js中添加你自己的組件。這里我們只是簡單的添加一個組件,然后用一個帶有樣式的組件把它包起來。

'use strict';

import React from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';

class RNHighScores extends React.Component {
  render() {
    var contents = this.props["scores"].map(
      score => <Text key={score.name}>{score.name}:{score.value}{"\n"}</Text>
    );
    return (
      <View style={styles.container}>
        <Text style={styles.highScoresTitle}>
          2048 High Scores!
        </Text>
        <Text style={styles.scores}>    
          {contents}
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#FFFFFF',
  },
  highScoresTitle: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  scores: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

// 整體js模塊的名稱
AppRegistry.registerComponent('RNHighScores', () => RNHighScores);

RNHighScores是整體js模塊(即你所有的js代碼)的名稱。你在iOS原生代碼中添加React Native視圖時會用到這個名稱。

8.集成RCTRootView

現在我們已經在index.ios.js中創建了React Native組件,下一步就是把這個組件添加給一個新的或已有的ViewController。

簡單起見:直接通過項目StoryBoard來創建一個按鈕,並添加點擊事件到ViewController了中。

Snip20170405_2.png

9.事件處理

首先導入RCTRootView的頭文件。
#import <React/RCTRootView.h>
【這塊和中文網上有出入,中文網導入有誤】

這里我們在btn的點擊方法中添加如下代碼

- (IBAction)highScoreButtonPressed:(id)sender {
    NSLog(@"High Score Button Pressed");
    NSURL *jsCodeLocation = [NSURL
                             URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios"];
    RCTRootView *rootView =
      [[RCTRootView alloc] initWithBundleURL : jsCodeLocation
                           moduleName        : @"RNHighScores"
                           initialProperties :
                             @{
                               @"scores" : @[
                                 @{
                                   @"name" : @"Alex",
                                   @"value": @"42"
                                  },
                                 @{
                                   @"name" : @"Joel",
                                   @"value": @"10"
                                 }
                               ]
                             }
                           launchOptions    : nil];
    UIViewController *vc = [[UIViewController alloc] init];
    vc.view = rootView;
    [self presentViewController:vc animated:YES completion:nil];
}

10. 調試前准備

現在基本的准備工作已經做完了,可以開始准備測試了。

修改App Transport Security

蘋果默認不允許app訪問不安全的http連接。這里我們通過在plist文件中添加如下key即可解決

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

運行Packager

From the root of your project, where the `node_modules` directory is located.

$ npm start

運行應用

如果你使用的是Xcode,那么照常編譯和運行應用即可。如果你沒有使用Xcode(但是你仍然必須安裝Xcode),則可以在命令行中使用以下命令來運行應用:

在項目的根目錄中執行:

$ react-native run-ios

運行效果

這個小程序中,你運行了之后點擊 High Score會出現如下頁面,表示集成成功了

Snip20170405_6.png

至此,就可以做功能的開發了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM