zoukankan      html  css  js  c++  java
  • react native 之 在现有的iOS工程中集成react native

    在现有的iOS工程中集成react native, 或者说将react native引入到iOS 项目,是RN和iOS混合开发的必经之路

    参考官网教程:https://reactnative.cn/docs/integration-with-existing-apps/

    但是会有一些步骤报错,这里记录一下。首先我的项目结构是这样:

    RNTEST 是最外面的文件夹的名字,也是iOS项目的名字。ios/  下是iOS项目文件。

    npm安装RN依赖都没问题,按照官网步骤来

    最主要的是

    cd ios

    pod install

    会报错。。。

    错误提示是找不到XXX索引库,在Podfile文件中将这些对应的注释掉:

    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

    此文仅为鄙人学习笔记之用,朋友你来了,如有不明白或者建议又或者想给我指点一二,请私信我。liuw_flexi@163.com/QQ群:582039935. 我的gitHub: (学习代码都在gitHub) https://github.com/nwgdegitHub/
  • 相关阅读:
    Chrome下载无后缀问题
    duilib程序HelloWorld
    go的windows下的安装包
    ASP.NET MVC异步上传图片和富文本编辑器的使用详解
    搭建go环境(windows和linux)
    构建离线Go编程指南——gotour
    判定模块加载时是否存在循环依赖
    Winform开发框架之框架演化
    为什么要写技术博
    JTREE使用例子—创建一个客户端界面
  • 原文地址:https://www.cnblogs.com/liuw-flexi/p/11698896.html
Copyright © 2011-2022 走看看