react native 之 在現有的iOS工程中集成react native

在現有的iOS工程中集成react native, 或者說將react native引入到iOS 項目,是RN和iOS混合開發的必經之路node

參考官網教程:https://reactnative.cn/docs/integration-with-existing-apps/react

可是會有一些步驟報錯,這裏記錄一下。首先個人項目結構是這樣:ios

RNTEST 是最外面的文件夾的名字,也是iOS項目的名字。ios/  下是iOS項目文件。git

 

npm安裝RN依賴都沒問題,按照官網步驟來github

最主要的是npm

cd iosjson

pod installreact-native

會報錯。。。app

 

 

 

錯誤提示是找不到XXX索引庫,在Podfile文件中將這些對應的註釋掉:ide

Podfile文件參考:https://github.com/facebook/react-native/blob/v0.60.0/template/ios/Podfile

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

target 'RNTEST' do
  # Pods for HelloWorld
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native'
  #pod 'React-DevSupport', :path => '../node_modules/react-native/React'
  #pod 'React-fishhook', :path => '../node_modules/react-native/Libraries/fishhook'
  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-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket'

  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 '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'


  use_native_modules!
end

 

結果:

 

以後就是在iOS工程中寫相關代碼, 能夠運行起來,可是在Native調RN時

而後發現又報錯了,改了package.json中的版本以下:

 就能夠了。

iOS項目代碼參考的是慕課網上的教程。

 

要想在iOS中加載一個JSX頁面,有兩種方式:

一:在控制器導入頭文件

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

而後加載JSX中註冊的模塊

//    NSURL *jsCodeLocation;
//
//    jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
//
//    RCTRootView *rootView =
//    [[RCTRootView alloc] initWithBundleURL: jsCodeLocation
//                                moduleName: @"App"
//                         initialProperties:nil
//                             launchOptions: nil];
//    self.view = rootView;

上面這個moduleName (任意取,可是要與OC中一致才能加載對應頁面)就是在index.js中的這個:

import {AppRegistry} from 'react-native'
import App from './App';
import App2 from './App2';
AppRegistry.registerComponent('App1',()=>App);
AppRegistry.registerComponent('App2',()=>App2);

AppRegistry.registerComponent('App3',()=>App2);

 

二:借鑑AppDelegate中加載方式,首先導入頭文件,遵循代理,實現代理方法,加載index.js中的模塊

//
//  RNPageController.m
//  RNTEST
//
//  Created by LiuWei on 2019/10/18.
//  Copyright © 2019 udc. All rights reserved.
//

#import "RNPageController.h"

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


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


@interface RNPageController ()<RCTBridgeDelegate>

@end

@implementation RNPageController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
//    [self initRCTRootView];

    RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:nil];
    RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                     moduleName:@"App1"
                                              initialProperties:nil];
    self.view=rootView;
}

//-(void)initRCTRootView{
//    NSURL *jsCodeLocation;
//
//    jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
//
//    RCTRootView *rootView =
//    [[RCTRootView alloc] initWithBundleURL: jsCodeLocation
//                                moduleName: @"App"
//                         initialProperties:nil
//                             launchOptions: nil];
//    self.view = rootView;
//}

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

 

以上這種開發方式最終打包 ipa時,

 

先在ios/ 下建立一個 release_ios/

而後執行命令生成必要的jsbundle文件和圖片資源文件

react-native bundle --entry-file index.js --platform ios --dev false --bundle-output release_ios/main.jsbundle --assets-dest release_ios/
  • --platform ios:表明打包導出的平臺爲iOS;
  • --dev false:表明關閉JS的開發者模式;
  • -entry-file index.js:表明js的入口文件爲index.js
  • --bundle-output:後面跟的是打包後將JS bundle包導出到的位置;
  • --assets-dest:後面跟的是打包後的一些資源文件導出到的位置;

 好了以後將生成必要的jsbundle文件和圖片資源文件拖進iOS項目

接下來就能夠打包了

 

特別注意:若是項目用到了CodePush熱更新:加載js文件的方式變成這樣

...
  NSURL *jsCodeLocation;
#ifdef DEBUG     jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else     jsCodeLocation = [CodePush bundleURL];
#endif ...

 

 

 

 

 

最後Demo地址:https://github.com/nwgdegitHub/OCCallRNDemo.git

相關文章
相關標籤/搜索