基于CocoaPods的 React Native新手入门

Posted 58无线技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于CocoaPods的 React Native新手入门相关的知识,希望对你有一定的参考价值。

相信大家已经阅读过我们水滴项目中的一系列文章,比如《基于React Native的58 APP开发实践》、《亲手搭建React Native热更新》、《一种React Native通用载体页的实现》、《React Native自定义模块实战》等文章。我的这篇文章不同于官网的helloworld新手教程,是基于咱们的项目架构而出的新手教程,从ios端来阐述新手如何将cocoapod、自定义组件、JS调试代码等融合起来,搭建一个适应于多部门合作新手开发脚手架。

本文包括的主要内容为:

一)、如何在已有的项目中集成RN

二)、如何根据业务开发RN组件

三)、FE业务端如何调用RN组件开发JS

四)、如何调试


一、  已有项目集成React Native

一)、创建React Native的pod库

      目前绝大多数app都采用了cocoapods来管理工程,所以我们选择把React Native库也制作成pod,通过cocoapods来管理。

为什么我们不直接通过pod引用原生的React Native,而是自己制作一个pod库?答案会在第二部分给出。

开发者需要在mac上安装cocoapods,以下是自己封装RN pod库的步骤:

1、github下载指定版本(一般是最新版)的ReactNative库并解压,得到react-native-master,备用;

2、创建一个名为WBReactNativeLibrary的目录,并在WBReactNativeLibrary下继续创建WBReactNativeLibrary/react-native,这里多包了一层WBReactNativeLibrary,是因为这一层还需要有一个spec文件来配置内部文件的引用;

3、找到react-native-master下的React.podspec,拷贝到WBReactNativeLibrary根目录下,改名为WBReactNativeLibrary.podspec;

4、根据以上podspec,把react-native-master下的Libraries、React拷贝到react-native下;

5、在WBReactNativeLibrary下添加README.md;

以下图1是WBReactNativeLibrary完整目录:


图1 WBReactNativeLibrary pod文件结构

以下图2是与react-native-master的对应关系,左侧是RN pod库的文件结构,右侧是RN原始结构。我们并不会把RN原始结构中的所有文件都拿到自己的pod中,而是根据podspec文件来引用有用的那些。     

基于CocoaPods的 React Native新手入门

图2 对应关系

6、修改WBReactNativeLibrary的podspec。

修改s.name  = "WBReactNativeLibrary",并根据实际路径,修改索引路径:

基于CocoaPods的 React Native新手入门
图3 索引路径的变化对比

注:s.subspec 'RCTTest':引用RCTTest时遇到错误,暂未解决。对使用RN开发无影响,所以删除掉。

7、注释代码

这一步是可选的,RN在解析时调用到JSONKit的解析方法,在某些版本上可能会存在crash的情况,如果崩溃在这里(见图4),注释掉RCTUtils.m文件的48-50行即可,程序会执行第57行的系统json解析方法。

基于CocoaPods的 React Native新手入门

图4 可能引起crash的代码块

二)、托管React Native pod库到git服务器

      这里我们选择github作为托管服务器,实际项目更偏向于选择公司内部提供的服务,如58的。推荐使用Github Desktop工具。

托管过程不具体说明,托管成功后会是以下这样:

基于CocoaPods的 React Native新手入门

5 pod库托管成功

三)、已有项目集成RN库

       我们以” 58同城”app为例,作为已有项目来实验RN的集成。

      打开工程目录下的podfile,增加对WBReactNativeLibrary的引用:

基于CocoaPods的 React Native新手入门

6 引用WBReactNativeLibrarypod

保存podfile后,终端运行pod update,即可看到WBReactNativeLibrary库已经集成到了” 58同城”工程中。

基于CocoaPods的 React Native新手入门

图7 WBReactNativeLibrary引入到” 58同城” 工程


 二、  组件开发

为什么不直接引用RN,而是自己制作一个新的pod库?

React Native已经提供了一些原生的、通用的组件,但这些组件往往无法满足app业务的需要。所以需要app RD自己来开发业务需要的自定义组件。

所以我们制作了WBReactNativeLibrary pod,里面不但包含RN提供的原生组件,还包含了自己开发的自定义组件。这样把RN作为一个独立的项目,而不是分散在app的多个地方。

我们会在WBReactNativeLibrary pod库中新建一个WBRCTComponent目录来保存自定义组件,与RN原生组件(react-native中)区分。

组件的开发有固定的套路,那就是实现<RCTBridgeModule>协议。组件大体分为两类:API组件和UI组件。

一)、UI组件,以实现一个loading组件为例:

1、配置组件的文件路径。在WBRCTComponent目录下创建RCTWBLoadingBar目录,用来保存loading组件;

2、创建组件的类文件;

这两步的结果如图8,RCTWBLoadingBar是对外保留的组件,而WBLoadingAnimationView被RCTWBLoadingBar所引用。因为自定义组件一般是业务相关的,很可能还会引用其他pod中的类、方法,直接引用即可。

基于CocoaPods的 React Native新手入门

图8 loading组件目录

3、修改WBReactNativeLibrary.podspec,配置引用路径,如下图:

基于CocoaPods的 React Native新手入门

图9 podspec 中配置loading组件

      4、RCTWBLoadingBar实现<RCTBridgeModule>协议。首先要注册Module,通过RN封装的宏定义RCT_EXPORT_MODULE来实现;其次通过宏定义RCT_EXPORT_METHOD来封装对外(JS)暴露的方法,如下图10,我们封装了execute:的方法,这个方法在JS中可以直接访问。

基于CocoaPods的 React Native新手入门

图10 loading组件的类实现

      注:组件类可能引用其他的类,组件方法也可能会调用其他的方法,只需要引用即可。其他的类或者方法对JS来说是不可见的,不需要通过以上宏定义来封装。

二)、API组件,以实现一个埋点组件为例:

基于CocoaPods的 React Native新手入门

图11 埋点组件的类实现

      组件方法中,会调用native已有的埋点方法(setTrackJsonWithPagetype:action: params),所以要引用其头文件#import"WBUserLog.h"。该组件并不提供一个UI来显示,而是实现一个功能。像定位功能、跳转功能等都属于API组件。

好了,WBReactNativeLibrary pod已经完成了组件的实现,把组件更新上传到github服务器上,” 58同城”工程目录下执行”podupdate”,打开工程即可看到组件了。

 

三、  JS业务部分

RN组件,不管是原生组件还是自定义组件,使用方都是FE前端,都是在JS中来调用的。在看JS如何调用组件之前,我们先看一下facebook官方提供的AwesomeProject Demo中native中怎么加载RN:

基于CocoaPods的 React Native新手入门

图12 native加载index.ios.js

可以看到,RN组件的入口是作为一个视图被native调用。

我们用JS开发了一个简单的页面,来测试前面开发的自定义组件。通过这种方式,看JS业务端是如何使用组件的。

一)、配置运行环境

1、首先安装React Native环境(http://facebook.github.io/react-native/docs/getting-started.html)。

2、把前面一中下载的下载指定版本的ReactNative库的解压包react-native-master拷贝到”58同城”根目录下。

3、进入react-native-master目录,运行npm install。作用是按照RN依赖的node_modules。

二)、实现JS代码

1、在react-native-master目录下创建Demo目录;在Demo目录下,创建一个index.ios.js文件。

2、实现index.ios.js。如下图13。我们实现了一个简单的ListView,cell有两个,一个是作为header的一行标题”list”,另一个是前面实现的loadingBar组件。最后的AppRegistry是JS运行所有React Native应用的入口。应用的根组件应当通过AppRegistry.registerComponent方法注册自己,然后原生系统才可以加载应用的代码包并且在启动完成之后通过调用AppRegistry.runApplication来真正运行应用。

基于CocoaPods的 React Native新手入门

图13 index.ios.js

      3、实现RCTWBLoadingBar.ios.js

      index.ios.js提供了一个可以扩展的ListView。目前提供的测试组件是RCTWBLoadingBar。为了降低耦合,我们把RCTWBLoadingBar组件的测试代码保存到独立文件中。以下图14是组件的部分测试代码,其中22-24行是最核心的测试代码,与图10对应,测试了对组件的调用。

      以后开发更多的组件时,我们会继续在ListView中扩展。


基于CocoaPods的 React Native新手入门

图14 loading组件的JS测试代码

三)、创建本地服务器环境

终端进入58tongcheng/react-native-master目录,然后运行npm start,会把该路径创建为一个本地服务器。我们没有在其中的Demo目录下执行,是因为还需要node_modules的配置文件。如图15,表示创建成功。

基于CocoaPods的 React Native新手入门

图15 创建本地服务器环境

四)、在”58同城” app native代码中访问index.ios.js

      为了方便测试,我们改写了”58同城”app中一个按钮的行为,使其加载RN页面。


基于CocoaPods的 React Native新手入门

图16 native访问index.ios.bundle

五)、运行

      在真机上运行app,点击触发RN的按钮,调用以上图16中的方法。然后就可以看到index.ios.js提供的RN页面了。

真实的业务开发,JS代码会复杂很多。

 

四、  调试

想要React Naitve能够在app内正常”跑”起来,需要保证native代码和JS代码都是正确无误的。RN提供了YellowBox(黄屏警告)与RedBox(红屏报错)。Native代码很容易跟踪调试,而调试JS代码就不是那么容易。还好facebook为我们提供了方法,见图17。


基于CocoaPods的 React Native新手入门

图17 调试方法

      1、首先要保证本地服务器环境搭建完成,见图15。

      3、在浏览器打开http://localhost:8081/debugger-ui页,并按下command + option + i;

      4、运行”58同城”app,进入RN页面,然后摇一摇设备,即可看到图18的调试窗口,选择”Debug JS Remotely”。

基于CocoaPods的 React Native新手入门

图18 调试菜单

      5、Chrome浏览器,,选择查看Sources,就能查看JS代码,并打断点调试了。如下图19,在RCTWBLoadingBar.ios.js文件的第22行打断点,点击loading cell就执行到这里。像Xcode断点调试一样,可以一步步执行,更方便地调试JS代码。


图19 在Chrome中调试JS代码

      至此,我们已经把React Native集成到了已有项目中,并且自己开发了组件,并且在JS中调用、测试成功了,还学会如何调试。



以上是关于基于CocoaPods的 React Native新手入门的主要内容,如果未能解决你的问题,请参考以下文章

React Native 使用 Cocoapods

让 CocoaPods 与 React Native 一起工作的问题

Cocoapods 在设置 react-native 开发时无法下载依赖项(APPLE M1)

React-Native:错误:无法为 iOS 项目安装 CocoaPods 依赖项,这是此模板所需的

无法通过 CocoaPods 构建 React Native 0.61.1

react-native-Cocoapods-Swift-Project