iOS原生項目集成ReactNative(持續更新)

前言

最近發現很多app都使用了ReactNative這門火熱的技術,不禁虎軀一震,因為公司的工作相對安逸,自己一直打算學習一下,但每次都不了了之,這次又默默看了看招聘信息,RN已經勢不可擋,新的一年想升職加薪看來要努力啦!
下面進入我們的主題,在iOS原生項目中集成ReactNative,鼓搗了一天終于成功了,鑒于市面上的資料都有些老舊了,所以我將我的經驗分享給大家,趕緊上車,落后就要挨打。

tips:如果操作過程中碰到什么錯誤或問題,請到文章最后問題合集中查看是否有解決辦法

一、準備工作

本文使用的版本
"react": "16.0.0",
"react-native": "0.51.0"

1、搭建開發環境

如果你已經創建過RN項目,并且運行成功了,那么你的環境配置肯定是沒有問題的,但是如果你是第一次進行學習,那么就要搭建開發環境了,具體的可以參考搭建ReactNative開發環境,搭建好后你可以按照他的提示創建一個RN項目運行一下,看環境是否成功

2、安裝CocoaPods

CocoaPods相信每一個iOS開發者都有接觸吧,如果你沒有使用過也沒關系,參考CocoaPods的安裝使用和常見問題這篇文章學習下吧。
本文只提供CocoaPods安裝React Native的方式,這個簡單易用。
這里就不提供手動集成的辦法了,因為筆者也沒嘗試過,如果有需要可以自己查資料。

二、集成ReactNative

1、文件配置

1)創建存放文件夾RNComponent和配置文件package.json

在項目中創建文件夾RNComponent并創建package.json配置文件,文件夾名字可以自定義,主要用來存放RN相關的文件,如下圖

//package.json 終端創建方法
$ cd 需要放置的目錄下(項目的根目錄/項目中自己創建的文件夾)
$ touch package.json
文件目錄.png

package.josn 中的內容如下,其中name位App的名字,dependencies為react和react-native的版本,在創建這些信息時,建議利用react-native init AwesomeProject新建新項目時會自動創建package.json,直接把文件復制過來,更改name為自己的原生項目名,確保信息為最新的,且不容易出錯。

{
  "name": "RNExample",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "react": "16.0.0",
    "react-native": "0.51.0"
  },
  "devDependencies": {
    "babel-jest": "22.0.4",
    "babel-preset-react-native": "4.0.0",
    "jest": "22.0.4",
    "react-test-renderer": "16.0.0"
  },
  "jest": {
    "preset": "react-native"
  }
}

2)安裝React Native依賴包

進入到RNComponent文件夾下運行命令行

npm install

執行結束后項目中會多出一個node_modules文件夾。

執行指令.png
執行結果png

看到有的文章說這里執行起來很慢,但是我這里很快,圖中看見27.596s,可能是因為我在配置環境的時候使用了淘寶鏡像,建議大家也這么做,搭建ReactNative開發環境里面有方法。

2、創建入口文件index.ios.js

終端創建方法

$ cd 需要放置的目錄下(項目的根目錄/項目中自己創建的文件夾)
$ touch index.ios.js
image.png

我這里開發使用的工具是WebStorm,這里可以分享下我的下載地址

index.ios.js 代碼如下

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

class RNExample 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('App', () => RNExample);

3. Cocoapods集成React Native

如果還沒有使用CocoaPods

$ cd 項目的根目錄
$ touch Podfile
$ open -e Podfile
$ pod install //只是注釋,在內容添加保存后執行
image.png

Podfile中添加的內容,添加后保存,然后執行 pod install

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, ‘9.0’
use_frameworks!

target ‘RNExample’ do
  # 'node_modules'目錄一般位于根目錄中
  # 但是如果你的結構不同,那你就要根據實際路徑修改下面的`:path`
  pod 'React', :path => ‘./RNComponent/node_modules/react-native', :subspecs => [
    'Core',
    'BatchedBridge', # 0.45 版本以后需要添加
    'DevSupport', # 如果RN版本 >= 0.43,則需要加入此行才能開啟開發者菜單
    'RCTText',
    'RCTImage',
    'RCTNetwork',
    'RCTWebSocket', # 這個模塊是用于調試功能的
    # 在這里繼續添加你所需要的模塊
  ]
  # 如果你的RN版本 >= 0.42.0,則加入下面這行
  pod “yoga", :path => “./RNComponent/node_modules/react-native/ReactCommon/yoga"

end

注:上面添加的有注釋的幾個都是查找多處資料找到的,好多老的資料都不可行了

執行結果:


image.png

三、項目處理

1、打開項目

使用CocoaPods后需要用箭頭所示文件打開


image.png

2、添加RCTRootView

這里只是在ViewController中進行了測試,具體放在什么地方,怎么放置大家根據項目需求而定

#import "ViewController.h"
#import <React/RCTRootView.h>
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
    button.center = self.view.center;
    [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    [button setTitle:@"Hello" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)buttonAction{
    NSString * strUrl = @"http://localhost:8081/index.ios.bundle?platform=ios&dev=true";
    NSURL * jsCodeLocation = [NSURL URLWithString:strUrl];
    
    RCTRootView * rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                         moduleName:@"App"
                                                  initialProperties:nil
                                                      launchOptions:nil];
    self.view = rootView;
}

@end

3、配置App Transport Security

在iOS 9以上的系統中,除非明確指明,否則應用無法通過http協議連接到localhost主機。 建議在Info.plist進行如下設置,否則會報Could not connect to development server錯誤


image.png

4、開啟服務器

在運行我們的項目之前,我們需要先啟動我們的開發服務器。進入 RNComponent目錄 ,然后命令行啟動服務:

react-native start

5、運行程序

我這里是用Xcode運行的項目,指令沒有運行起來,很尷尬。
項目跑起來,very good??,這里只是在模擬器上運行,真機上運行請見問題合集2

image.png

之前一直報錯無法連接服務器,現在我覺得問題就是沒有執行第四部開啟服務器,如果有什么問題請留言交流,下面有個問題集合,我以后遇到的問題都會收集起來,希望對大家有所幫助,共同進步。

6、吃水不忘挖井人

參考鏈接:
http://www.lxweimin.com/p/3dc9d70a790f
https://reactnative.cn/docs/0.42/getting-started.html
http://www.lxweimin.com/p/47174bf215bf

四、問題集合

問題都是我在開發中遇到的,情況不同解決方法可能不同僅供參考

1、'fishhook/fishhook.h' file not found

image.png

解決辦法:將#import <fishhook/fishhook.h> 改為 #import "fishhook.h"即可

2、Could not connect to development server

如果正常的話http://localhost:8081/index.ios.bundle?platform=ios&dev=true將會有內容
解決辦法:

  • 1、是否配置App Transport Security
  • 2、是否開啟服務器,執行react-native start
  • 3、真機上運行報錯
    如果模擬器上是可以的而在真機上運行報上面的錯誤請按下面步驟執行,
    打開設置-網絡-查看當前ip地址,將項目中的localhost改為當前ip(注意,手機的wifi應當和電腦的wifi是同一個才可以)


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

推薦閱讀更多精彩內容