在已有 OC 项目无痛集成 React Native

基本要求

  • Cocoapods 使用熟悉
  • 熟悉 Mac 基本操作
  • 解决问题的基本功

官方示例

这是官方给出的教程,集成到现有原生应用,按照这个集成的跑起来没啥问题,但是后期等你用了一些组件,或原生或 RN 的,比如自定义 UIViewRN 用,RN 里用的第三方的 component 调用了原生的 API,官方的这些默认的 pod 库就是缺少一些的,跑项目会出一些莫名其妙的问题,我在用了react-navigation后各种运行时红屏报错问题,错误提示也看不出个所以然来,折腾好久才解决问题,这里我将直接记录主要过程和注意点,以备不时之需。

踩坑后的做法

  • 根据官方给出的搭建开发环境配置好环境
  • 这时已经装好了react-native-cli,随便init一个新项目出来
  • 创建一个文件夹,准备用来存放集成 RN 的项目,比如 ProjectIntegrateRN
  • 拷贝app.jsonnode_modulespackage.json 文件\文件夹 到ProjectIntegrateRN 文件夹
  • 拷贝原来的 OC\Swift 项目至 ProjectIntegrateRN 文件夹

这里假设项目已经使用了 Cocoapods 管理第三方库,进入原生OC\Swift项目根目录,执行:

☁  puma [RN-integration] vim Podfile

加入React Native的依赖:

def rnpods
    pod 'React', :path => "../node_modules/react-native", :subspecs => [
      "Core",
      "ART",
      "RCTActionSheet",
      "RCTAnimation", # FlatList和原生动画功能需要此模块
      "RCTCameraRoll",
      "RCTGeolocation",
      "RCTImage",
      "RCTNetwork",
      "RCTText",
      "RCTVibration",
      "RCTWebSocket", # 调试功能需要此模块
      "DevSupport", # 如果RN版本 >= 0.43,则需要加入此行才能开启开发者菜单
      "CxxBridge", # 如果RN版本 >= 0.47则加入此行
      # 在这里继续添加你所需要的其他RN模块
        #'RCTAdSupport',
       'RCTPushNotification',
       'RCTSettings',
       'RCTLinkingIOS']
        
  # 如果你的RN版本 >= 0.42.0,则加入下面这行
  pod 'yoga', :path => "../node_modules/react-native/ReactCommon/yoga"

  # 如果RN版本 >= 0.45则加入下面三个第三方编译依赖
  pod 'DoubleConversion', :podspec => "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
  pod 'Folly', :podspec => "../node_modules/react-native/third-party-podspecs/Folly.podspec"
  pod 'glog', :podspec => "../node_modules/react-native/third-party-podspecs/glog.podspec"
  
  pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
end

开始使用

rnpods 加入到 Target "your_scheme" pod update或者pod install等结束,不出意外的话应该能跑了.

更改默认 node 端口

RN项目目录执行:

☁  puma [RN-integration] mvim node_modules/react-native/local-cli/server/server.js

CTRL+F查找 8081 替换为你想要的端口,比如换成 6666

原生代码里记得更改,比如 OC 项目里这样改:

NSURL *jsCodeLocation;

// node
jsCodeLocation = [NSURL URLWithString:@"http://localhost:6666/src/index.bundle?platform=ios"];

// 如果打包或真机,使用下面这个
//    jsCodeLocation = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"index.jsbundle" ofType:nil]];

_rnView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                      moduleName:@"DongKe"
                               initialProperties:
                                   @{
                                       @"enterpriseID": self._id,
                                       @"source": @(self.source)
                                   }
                                   launchOptions:nil];