美文网首页react-native相关
react native 集成到 ios 项目中

react native 集成到 ios 项目中

作者: LightReason | 来源:发表于2020-03-10 11:50 被阅读0次

    出于公司需求,需要再已经运行了5年的项目中添加react native .看到网上基本上就是照抄RN中文网的, 时间也很久了, 把自己集成的过程记录下,尝试总结下 ,希望帮助需要的人吧。

    1.RN环境

    我们的开发电脑安装RN的环境, 这里就不多做介绍了,RN中文网写的很详细。

    2. 安装 JavaScript 依赖包

    在项目根目录下创建一个名为package.json的空文本文件,填入内容,填入什么内容呢?
    其实你可以使用react-native init 项目名命令创建一个纯RN项目,然后去参考其ios目录中的package.json 和 Podfile文件【备注:RN的最新版本0.6+开始使用cocopods管理ios项目,并管理ios和RN的项目依赖】

    这里简单贴一下示例:
    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"
      }
    }
    

    然后运行yarn add react-native
    这样默认会安装最新版本的 React Native,同时会打印出类似下面的警告信息(你可能需要滚动屏幕才能注意到):
    warning "react-native@0.52.2" has unmet peer dependency "react@16.2.0".
    这是正常现象,意味着我们还需要安装指定版本的 React:
    yarn add react@16.2.0
    注意必须严格匹配警告信息中所列出的版本,高了或者低了都不可以。
    如果你使用多个第三方依赖,可能这些第三方各自要求的 react 版本有所冲突,此时应优先满足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
    
    

    这里需要注意两点

    【1】Podfile 文件中,node_modules 目录一般位于根目录中 但是如果你的结构不同,那你就要根据实际路径修改下面的:path =>

    我贴一下我示例项目中的目录结构


    截屏2020-03-1010.51.01.png
    【2】Podfile 文件中,platform :ios, '9.0' 这个要注意 一定最低是9.0 否则pod instal的时候会出现类似Folly glog DoubleConversion 安装不上,包错误❌的问题。可以试一下。

    剩下的就是 pod install了,如果这个过程不出错,恭喜你!!已经基本完成了项目集成RN的工作~

    其实说白了 就两大步, 搞定package.jsonPodfile

    剩下的就是在根目录中新建一个index.js的RN入口文件,和在OC中调用进入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 -> 跳转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. 下面我说下 我项目中遇到的坑

    【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

    最后的最后, 我兴奋的运行了起来, 完美 perfect !成功了耶,于是打包测试, WC,跳转到RN界面 居然 闪退了!!!

    嘚吧了那么多,其实还有一小点需要我们注意,这个是原项目集成RN中容易忽略的点,

    先解释一下吧,
    其实在release 环境下打包 代码中有这样一句

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

    那么这个main.jsbundle怎么生成呢,我也网上找了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
    我都试一试了,反正在我这边都不行, 打包后一跳转RN界面就会闪退,

    其实在RN中文网集成到现有项目中一段未翻译的英文标注

    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脚本 添加到 你项目中

    截屏2020-03-1011.26.59.png

    就是这个Bundle React Native code and images 内容如下:

    export NODE_BINARY=node
    ../node_modules/react-native/scripts/react-native-xcode.sh
    
    
    截屏2020-03-1011.29.34.png

    注意路径哦,个别项目可能不同

    ~ 另外 我的项目 刚集成了 RN 的热更库 微软的 code-push 有时间写也一下集成历程...

    到此真正的结束了,你可以愉快的 codeing rn 代码了...

    相关文章

      网友评论

        本文标题:react native 集成到 ios 项目中

        本文链接:https://www.haomeiwen.com/subject/pjwidhtx.html