前言
最近發現很多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
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文件夾。
看到有的文章說這里執行起來很慢,但是我這里很快,圖中看見27.596s,可能是因為我在配置環境的時候使用了淘寶鏡像,建議大家也這么做,搭建ReactNative開發環境里面有方法。
2、創建入口文件index.ios.js
終端創建方法
$ cd 需要放置的目錄下(項目的根目錄/項目中自己創建的文件夾)
$ touch index.ios.js
我這里開發使用的工具是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 //只是注釋,在內容添加保存后執行
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
注:上面添加的有注釋的幾個都是查找多處資料找到的,好多老的資料都不可行了
執行結果:
三、項目處理
1、打開項目
使用CocoaPods后需要用箭頭所示文件打開
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錯誤
4、開啟服務器
在運行我們的項目之前,我們需要先啟動我們的開發服務器。進入 RNComponent目錄 ,然后命令行啟動服務:
react-native start
5、運行程序
我這里是用Xcode運行的項目,指令沒有運行起來,很尷尬。
項目跑起來,very good??,這里只是在模擬器上運行,真機上運行請見問題合集2
之前一直報錯無法連接服務器,現在我覺得問題就是沒有執行第四部開啟服務器,如果有什么問題請留言交流,下面有個問題集合,我以后遇到的問題都會收集起來,希望對大家有所幫助,共同進步。
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
解決辦法:將#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