将RN集成到现有OC项目应该是最常见的,特别是已经有OC项目的,不太可能会去专门搞个纯RN的项目。又因为RN不同版本,引用的依赖可能不尽相同,所以特别说明下,本文参考的文档是React Native (0.57)相关文档。

一、准备工作

本文演示项目基于如下版本:

"react": "16.5.0",
"react-native": "0.57.1"

1、RN搭建开发环境

如果你已经创建过RN项目,并且运行成功了,那么你的环境配置应该是没有问题的,但是如果你是第一次进行学习,那么就要搭建开发环境了,具体的可以参考: React Native (0.57)开发环境搭建(过程记录)

2、安装CocoaPods

没有安装过CocoaPods的,可以参考:CocoaPods :为iOS程序提供依赖管理的工具(yoowei)

二、集成ReactNative

1、新建一个OC项目

任意地方,创建一个文件夹“OC项目集成RN”,创建一个yooweiRN的OC项目,用为已有OC项目。如下:

2、终端命令 cd 到该项目跟目录。创建文件夹RNComponent (文件夹名字可以自定义,主要用来存放RN相关的文件)和配置文件package.json

$ cd /Users/galahad/Desktop/ziliao/OC项目集成RN/RNComponent 
$ touch package.json
 
package.josn 中的内容如下,其中name位App的名字,dependencies为react和react-native的版本,在创建这些信息时,建议利用react-native init AwesomeProject新建新项目时会自动创建package.json,直接把文件复制过来,更改name为自己的原生项目名,确保信息为最新的,且不容易出错。
 

3、安装React Native依赖包

进入到RNComponent文件夹下运行命令行,npm install。
$ cd /Users/galahad/Desktop/ziliao/OC项目集成RN/yooweiRN/RNComponent 
$ npm install
执行结束后项目中会多出一个node_modules文件夹
 
使用镜像文件,执行很快
added 1033 packages from 527 contributors in 37.502s
 
4、创建入口文件index.js、参考官方生成的RN项目里面的文件
$ cd /Users/galahad/Desktop/ziliao/OC项目集成RN/yooweiRN/RNComponent
$ touch index.js
$ touch App.js
$ touch app.json

5. Cocoapods集成React Native

终端命令cd 到项目跟目录

$ cd /Users/galahad/Desktop/ziliao/OC项目集成RN/yooweiRN 
 
创建Podfile文件:
$ touch Podfile
$ open -e podfile
$ cd /Users/galahad/Desktop/ziliao/OC项目集成RN/yooweiRN 
$ pod install
(1)在安装的过程中遇到好多以前没有遇到的问题,下面一一记录下来,以供参考:
[!] CocoaPods could not find compatible versions for pod "React/BatchedBridge":
  In Podfile:
    React/BatchedBridge (from `./RNComponent/node_modules/react-native`)
None of your spec sources contain a spec satisfying the dependency: `React/BatchedBridge (from `./RNComponent/node_modules/react-native`)`.
You have either:
 * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
 * mistyped the name or version.
 * not added the source repo that hosts the Podspec to your Podfile.
Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.
然后我按照要求进行升级,升级的过程中又遇到了另外一个问题。(先透漏下,最终的原因不是因为没有升级,后面会讲到)
 
$ pod repo update
 遇到了一个问题
 /usr/bin/git -C /Users/galahad/.cocoapods/repos/WYNetWorking fetch origin --progress
  remote: Repository not found.
  fatal: repository 'https://github.com/yoowei/WYNetWorking.git/' not found
[!] CocoaPods was not able to update the `WYNetWorking` repo. If this is an unexpected issue and persists you can inspect it running `pod repo update --verbose`
 
这个是我原来自己建的库,已经废弃了,github上面的库已经删除,所以此次报这个错误。进入这个/Users/galahad/.cocoapods/repos/WYNetWorking目录下,将其删掉即可。
 
之后,还是报上面那个错误
 
[!] CocoaPods could not find compatible versions for pod "React/BatchedBridge":
 
那么我就认为这个根本就不是什么cocoapods 升不升级的问题,而是依赖存不存在的问题,所以在podfile 里面直接将BatchedBridge 删掉,然后pod install 能够成功。但是整个项目却报一堆错误
 
Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_RCTDevMenuItem", referenced from:
      objc-class-ref in RCTPerfMonitor.o
  "facebook::react::parseTypeFromHeader(facebook::react::BundleHeader const&)", referenced from:
      +[RCTJavaScriptLoader attemptSynchronousLoadOfBundleAtURL:runtimeBCVersion:sourceLength:error:] in RCTJavaScriptLoader.o
 
  。。。(省略)
 
  "_OBJC_CLASS_$_RCTInspectorDevServerHelper", referenced from:
      objc-class-ref in RCTBridge.o
      objc-class-ref in RCTDevSettings.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
 
转变思路,应该是引用的三方依赖库文件不对,这个时候,参考 https://reactnative.cn/docs/integration-with-existing-apps/
 
 
参考之后(注意可能不同版本不一样),编辑podfile 文件,如下:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
use_frameworks!

target 'yooweiRN' do
# 'node_modules'目录一般位于根目录中 。但是如果你的结构不同,那你就要根据实际路径修改下面的`:path`
pod 'React', :path => './RNComponent/node_modules/react-native', :subspecs => [
'Core',
'ART',
'RCTActionSheet',
'RCTGeolocation',
'RCTImage',
'RCTNetwork',
'RCTPushNotification',
'RCTSettings',
'RCTText',
'RCTVibration',
'RCTWebSocket',
'RCTLinkingIOS',
'RCTAnimation',
'CxxBridge',
'DevSupport',

]
pod 'yoga', :path => './RNComponent/node_modules/react-native/ReactCommon/yoga'

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

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

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

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

然后pod install 又特么出问题了
$ pod install
Analyzing dependencies
Fetching podspec for `DoubleConversion` from `./RNComponent/node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`
Fetching podspec for `Folly` from `./RNComponent/node_modules/react-native/third-party-podspecs/Folly.podspec`
Fetching podspec for `React` from `./RNComponent/node_modules/react-native`
Fetching podspec for `glog` from `./RNComponent/node_modules/react-native/third-party-podspecs/glog.podspec`
Fetching podspec for `yoga` from `./RNComponent/node_modules/react-native/ReactCommon/yoga`
Downloading dependencies
Installing DoubleConversion (1.1.6)
Installing Folly (2016.10.31.00)
Using React (0.57.1)
Installing boost-for-react-native (1.63.0)
Installing glog (0.3.5)
[!] /bin/bash -c 
set -e
#!/bin/bash
set -e
 
PLATFORM_NAME="${PLATFORM_NAME:-iphoneos}"
CURRENT_ARCH="${CURRENT_ARCH}"
 
......(省略)
 
xcrun: error: SDK "iphoneos" cannot be located
xcrun: error: SDK "iphoneos" cannot be located
xcrun: error: SDK "iphoneos" cannot be located
xcrun: error: unable to lookup item 'Path' in SDK 'iphoneos'
/Users/galahad/Library/Caches/CocoaPods/Pods/External/glog/2263bd123499e5b93b5efe24871be317-e8acf/missing: Unknown `--is-lightweight' option
Try `/Users/galahad/Library/Caches/CocoaPods/Pods/External/glog/2263bd123499e5b93b5efe24871be317-e8acf/missing --help' for more information
configure: WARNING: 'missing' script is too old or missing
configure: error: in `/Users/galahad/Library/Caches/CocoaPods/Pods/External/glog/2263bd123499e5b93b5efe24871be317-e8acf':
configure: error: C compiler cannot create executables
See `config.log' for more details
 
然后执行下面命令:
$ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/
输入mac密码
Password:
重新安装
$ pod install
安装没有问题,工程运行OK .
 

三、项目处理

项目目录:整个工程中新建一个文件夹 RNComponent ,用来装RN相关资料,显得整洁,便于管理。
 
工程目录结构:
 
注意工程目录结构中并没有将 RNComponent 拖进去,因为cocopods 已经引用过了相关的东西。
 
1、配置App Transport Security

在iOS 9以上的系统中,除非明确指明,否则应用无法通过http协议连接到localhost主机。 建议在Info.plist进行如下设置,否则会报Could not connect to development server错误。

2、添加RCTRootView
这里只是在ViewController中进行了测试,具体放在什么地方,怎么放置大家根据项目需求而定。
 

3、开启RN本地服务(cd 到RNComponent目录)

$ cd /Users/galahad/Desktop/ziliao/OC项目集成RN演练/yooweiRN/RNComponent

$ react-native start

不出意外的是下面这个场景

原因:打印日志看看

由于RN不同版本,入口文件名不同,根据实际入口文件名,修改之后。

模拟器展示如下:

4G真机上面运行失败 :(正常现象)

Failed to load bundle(http://localhost:8081/index.bundle?platform=ios&dev=true) with error:(Could not connect to development server.

wifi真机上面运行失败:

Ensure the following:

- Node server is running and available on the same network - run 'npm start' from react-native root

- Node server URL is correctly set in AppDelegate

- WiFi is enabled and connected to the same network as the Node Server

URL: http://localhost:8081/index.bundle?platform=ios&dev=true Could not connect to the server.)

打开偏好设置-网络-查看当前ip地址,将项目中的localhost改为当前ip(注意,手机的wifi应当和电脑连接的是同一个网络才可以)

至此,将RN集成进OC项目中,并简单的运行起来,告一段落。下面待续......

jsCodeLocation生成方式总结:

NSURL *jsCodeLocation;

/**

* OPTION 1:  development

* Load from development server. Start the server from the repository root:

* $ npm start

* To run on device, change `localhost` to the IP address of your computer, and make sure your computer and iOS device are on the same Wi-Fi network.

*/

jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios&dev=true"];

/**

* OPTION 2:Release

* Load from pre-bundled file on disk. The static bundle is automatically generated by the "Bundle React Native code and images" build step when  running the project on an actual device or running the project on the simulator in the "Release" build configuration.

*/

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

另外实际项目中,还有如下写法:

#ifdef DEBUG

jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

#else

jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"bundle/index.ios" withExtension:@"jsbundle"];

#endif

如果项目中使用了CodePush的话,还有如下写法

#ifdef DEBUG

jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];

#else

jsCodeLocation = [CodePush bundleURL];

#endif

说明:

上面的两个例子,JS代码包URL的获取是通过RCTBundleProvider这个类实现的。JS代码包的URL有两种可能结果,一种是Packager Server URL,一种是本地JS代码包的文件路径。通过jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];去获取JS代码包URL时,会首先检查是否有正在运行的Packager Server,如果有则返回相应Packager Server中JS代码包的绝对路径;如果没有正在运行的Packager Server,则会返回一个本地JS代码包的文件路径,不传递fallbackResource参数时,默认返回 本地main.jsbundle的文件路径。

将React Native 集成进现有OC项目中(过程记录) 、jsCodeLocation 生成方式总结的更多相关文章

  1. 将React Native集成至Android原生应用

    将React Native集成至Android原生应用 Android Studio 2.1 Preview 4生成的空项目 react-native 环境 0.22.2 初次编译后apk有1.1M, ...

  2. Angular团队公布路线图,并演示怎样与React Native集成

    本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2015/06/angular-2-react-native-roadmap 前不久在旧 ...

  3. react native 0.50与OC交互 && Swift与RN交互

    新公司也打算做rn,还是得捡起来再度学习.开撸! react native一个版本一个样子,之前写的rn与iOS交互系列在最新版本中有点出入(0.50.4版本).今天填一下坑. 首先上npm版本,re ...

  4. React Native 0.56.1初始化项目运行出现错误(Module `AccessibilityInfo` does not exist in the Haste module map)

    当使用react-native init myApp初始化项目时,出现以下错误 出现以上错误的原因是因为0.56.1版本初始化项目就有问题,请见 https://github.com/facebook ...

  5. React Native集成Redux框架讲解与应用

    学过React Native的都知道,RN的UI是根据相应组件的state进行render的,而页面又是由大大小小的组件构成,导致每个组件都必须维护自身的一套状态,因此当页面复杂化的时候,管理stat ...

  6. React Native环境配置、初始化项目、打包安装到手机,以及开发小知识

    1.前言 环境:Win10 + Android 已经在Windows电脑上安装好 Node(v14+).Git.Yarn. JDK(v11) javac -version javac 11.0.15. ...

  7. React Native技术做的一个项目“微笑阅读”

    最近用React Native做了一个APP应用,有点心得: React Native确实比Hybrid应用渲染快,响应快,用户体验更好: React Native比原生简单多了,会Js就可以了,开发 ...

  8. react native定报预披项目知识点总结

    1.TextInput组件对安卓的适配问题 textInput 在iOS 显示正常,但是在android下会出现下横线,并且字会被遮盖 因此一般都这么用该组件 <TextInput style= ...

  9. React-Native集成到已有项目中的总结

    安装Python 从官网下载并安装python 2.7.x(3.x版本不行) 安装node.js 从官网下载node.js的官方V6.X.X版本或更高版本.安装完成后检测是否安装成功:node -v ...

随机推荐

  1. Python自动化之traceback

    import traceback try: 11/a except Exception: b = traceback.format_exc() traceback.format_exc()会存储详细的 ...

  2. 如何解析json字符串及返回json数据到前端

    前言:最近需要实现的任务是:写若干个接口,并且接口中的请求数据是json格式,然后按照请求参数读取前端提前整理好的json数据,并且将json数据返回到服务器端. 主要的工具:Gson  2.8.2 ...

  3. CAN网要不要共地?

    重要:CAN网要不要共地? 因为CAN传输采用差分传输的方式,即使不共地,部分情况下仍然能传输数据,但是本人以实际的经验告诉你们,一定要共地! 1.         不共地会引入共模干扰,轻则影响正常 ...

  4. MapReduce -- 好友推荐

    MapReduce实现好友推荐: 张三的好友有王五.小红.赵六; 同样王五.小红.赵六的共同好友是张三; 在王五和小红不认识的前提下,可以通过张三互相认识,给王五推荐的好友为小红, 给小红推荐的好友是 ...

  5. 搞定flex布局

    这几种方式的搭配使用可以轻松搞定 PC 端页面的常见需求,比如实现水平居中可以使用 margin: 0 auto,实现水平垂直同时居中可以如下设置: .dad { position: relative ...

  6. 什么是X86和X86-64

    X86的定义 X86是一个Intel或AMD通用计算机系列的标准编号缩写,也是32位微处理器架构的一种,也标识一套通用的计算机指令集. X86-64的定义 X86-64,简称X64,是一个Intel或 ...

  7. Linux磁盘与文件系统管理(一)

    fdisk 常用的磁盘分区工具,受mbr分区表的限制,只能给小于2TB的磁盘划分分区,如果使用fdisk对大于2TB的磁盘进行分区,虽然可以分区,但只能识别2T的空间,一般使用parted分区工具 - ...

  8. jQuery----操作类样式(依托开关灯案例)

    在网页开发中,元素的样式可以在style标签中定义,但是有很多案例需要添加类样式或者删除类样式,可以获取元素调用css()方法改变元素样式,但是这种方法很繁杂,本文利用开关灯案例,小结使用jquery ...

  9. JavaWeb总结(四)

    使用Servlet发送服务器端响应信息 Servlet API中定义一个专门的接口类javax.servlet.http.HttpServletResponse用于创建HTTP响应,包括HTTP协议的 ...

  10. 使用Nginx+uWSGI+Django方法部署Django程序

    第一步先解决uwsgi与django的桥接.解决在没有nginx的情况下,如何使用uwsgi+DJANGO来实现一个简单的WEB服务器. 第二步解决uwsgi与Nginx的桥接.通过nginx与uws ...