react native 集成到 ios 項(xiàng)目中

出于公司需求,需要再已經(jīng)運(yùn)行了5年的項(xiàng)目中添加react native .看到網(wǎng)上基本上就是照抄RN中文網(wǎng)的, 時間也很久了, 把自己集成的過程記錄下,嘗試總結(jié)下 ,希望幫助需要的人吧。

1.RN環(huán)境

我們的開發(fā)電腦安裝RN的環(huán)境, 這里就不多做介紹了,RN中文網(wǎng)寫的很詳細(xì)。

2. 安裝 JavaScript 依賴包

在項(xiàng)目根目錄下創(chuàng)建一個名為package.json的空文本文件,填入內(nèi)容,填入什么內(nèi)容呢?
其實(shí)你可以使用react-native init 項(xiàng)目名命令創(chuàng)建一個純RN項(xiàng)目,然后去參考其ios目錄中的package.json 和 Podfile文件【備注:RN的最新版本0.6+開始使用cocopods管理ios項(xiàng)目,并管理ios和RN的項(xiàng)目依賴】

這里簡單貼一下示例:
package.json

{
  "name": "myRactNative",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "react": "16.9.0",
    "react-native": "0.61.5"
  },
  "devDependencies": {
    "@babel/core": "^7.8.7",
    "@babel/runtime": "^7.8.7",
    "@react-native-community/eslint-config": "^0.0.7",
    "babel-jest": "^25.1.0",
    "eslint": "^6.8.0",
    "jest": "^25.1.0",
    "metro-react-native-babel-preset": "^0.58.0",
    "react-test-renderer": "16.9.0"
  },
  "jest": {
    "preset": "react-native"
  }
}

然后運(yùn)行yarn add react-native
這樣默認(rèn)會安裝最新版本的 React Native,同時會打印出類似下面的警告信息(你可能需要滾動屏幕才能注意到):
warning "react-native@0.52.2" has unmet peer dependency "react@16.2.0".
這是正?,F(xiàn)象,意味著我們還需要安裝指定版本的 React:
yarn add react@16.2.0
注意必須嚴(yán)格匹配警告信息中所列出的版本,高了或者低了都不可以。
如果你使用多個第三方依賴,可能這些第三方各自要求的 react 版本有所沖突,此時應(yīng)優(yōu)先滿足react-native所需要的react版本。其他第三方能用則用,不能用則只能考慮選擇其他庫。

3. 安裝 Cocopods 依賴包

Podfile

platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target 'myRactNative' do
  # Pods for myRactNative
  pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
  pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
  pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
  pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/'
  pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
  pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
  pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'

  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
  pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
  pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
  pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'

  target 'myRactNativeTests' do
    inherit! :search_paths
    # Pods for testing
  end

  use_native_modules!
end

target 'myRactNative-tvOS' do
  # Pods for myRactNative-tvOS

  target 'myRactNative-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end

end

這里需要注意兩點(diǎn)

【1】Podfile 文件中,node_modules 目錄一般位于根目錄中 但是如果你的結(jié)構(gòu)不同,那你就要根據(jù)實(shí)際路徑修改下面的:path =>

我貼一下我示例項(xiàng)目中的目錄結(jié)構(gòu)


截屏2020-03-1010.51.01.png
【2】Podfile 文件中,platform :ios, '9.0' 這個要注意 一定最低是9.0 否則pod instal的時候會出現(xiàn)類似Folly glog DoubleConversion 安裝不上,包錯誤?的問題??梢栽囈幌?。

剩下的就是 pod install了,如果這個過程不出錯,恭喜你!!已經(jīng)基本完成了項(xiàng)目集成RN的工作~

其實(shí)說白了 就兩大步, 搞定package.jsonPodfile

剩下的就是在根目錄中新建一個index.js的RN入口文件,和在OC中調(diào)用進(jìn)入RN場景的代碼了,這里簡單貼一下代碼:

index.js

/**
 * @format
 */

import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

native view -> 跳轉(zhuǎn)RN

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"myRactNative"
                                            initialProperties: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];
  return YES;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

@end

4. 下面我說下 我項(xiàng)目中遇到的坑

【1】Pods/boost-for-react-native/boost/compatibility/cpp_c_headers/cstdlib:11:11: error: no member named 'abort' in the global namespace

解決辦法: Xcode: cstdlib no member named “xxx” in the global namespace

最后的最后, 我興奮的運(yùn)行了起來, 完美 perfect !成功了耶,于是打包測試, WC,跳轉(zhuǎn)到RN界面 居然 閃退了?。。?/h1>

嘚吧了那么多,其實(shí)還有一小點(diǎn)需要我們注意,這個是原項(xiàng)目集成RN中容易忽略的點(diǎn),

先解釋一下吧,
其實(shí)在release 環(huán)境下打包 代碼中有這樣一句

  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];

那么這個main.jsbundle怎么生成呢,我也網(wǎng)上找了rn代碼打包成bundle的命令 , 什么使用curl命令生成 main.jsbundle 還有什么react-native bundle --entry-file index.ios.js --bundle-output ./bundle/ios/index.ios.jsbundle --platform ios --assets-dest ./bundle/ios --dev false
我都試一試了,反正在我這邊都不行, 打包后一跳轉(zhuǎn)RN界面就會閃退,

其實(shí)在RN中文網(wǎng)集成到現(xiàn)有項(xiàng)目中一段未翻譯的英文標(biāo)注

When moving your app to production, the NSURL can point to a pre-bundled file on disk via something like [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];. You can use the react-native-xcode.sh script in node_modules/react-native/scripts/ to generate that pre-bundled file.
就是這個 react-native-xcode.sh script腳本

這個 react-native-xcode.sh script腳本 添加到 你項(xiàng)目中

截屏2020-03-1011.26.59.png

就是這個Bundle React Native code and images 內(nèi)容如下:

export NODE_BINARY=node
../node_modules/react-native/scripts/react-native-xcode.sh

截屏2020-03-1011.29.34.png

注意路徑哦,個別項(xiàng)目可能不同

~ 另外 我的項(xiàng)目 剛集成了 RN 的熱更庫 微軟的 code-push 有時間寫也一下集成歷程...

到此真正的結(jié)束了,你可以愉快的 codeing rn 代碼了...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容