浅述 RN 开发 APP
浅述 RN 开发 APP
需要安装的依赖有:Node、Watchman、Xcode 和 CocoaPods
CocoaPods

- CocoaPods 是 Swift 和 Objective-C Cocoa 项目的依赖管理器
- CocoaPods 管理 Xcode 项目的库依赖项
- 项目的依赖项在称为 Podfile 的单个文本文件中指定。CocoaPods 将解析库之间的依赖关系,获取生成的源代码,然后在 Xcode 工作区中将它们链接在一起以构建您的项目。
- CocoaPods是用 Ruby 编写的包管理器(可以理解为针对 iOS 的 npm)。从 0.60 版本开始 react native 的 iOS 版本需要使用 CocoaPods 来管理依赖. (需要科学上网的工具, 中间花费的时间可能会很长)
Metro

React Native 的 JavaScript 打包器
- 快速启动和快速捆绑
- 缓存构建并执行模块替换重新加载
- 在单个应用程序中使用数千个模块
- 开箱即用地支持每个 React Native 项目
初始化项目
参考文档
创建项目
npx react-native init MyDuck
注意
pod install
按照官方文档创建项目之后需要在 ios 文件夹下面安装 ios 应用需要的依赖包,需要网好能正常访问 github(依赖包需要去 github 上拉下来),部分依赖的包可能一次下不完整,多下载几次就行了,(在模拟器运行的时候缺少的包会有提示)

预览

RN 解析
架构

- JS 代码层提供了 React.js 支持
- React.js 的 JSX 代码转化为 JS 代码运行在 JavaScriptCore 提供的 JavaScript 运行时环境中
- 通信层将 JavaScript 与 Native 层连接起来
- 通信层又可以分为三部分,
其中 Shadow Tree 用来定义 UI 效果及交互功能、
Native Modules 提供 Native 功能(比如相册、蓝牙等)、
而他们之间的相互通信 使用的是 JSON 异步消息
线程

RN 运行时会创建三个线程:JS Thread、Shadow Thread、Main Thread,在这三个线程中分别会创建三棵树,JS 线程中会创建一棵树叫做 Fiber Tree,在 Shadow 线程中会创建一棵树叫做 Shadow Tree,在 UI 线程中则是 View Tree。其中,Fiber Tree 在 JS 侧创建,Shadow Tree 和 View Tree 在 Native 侧创建
- JS Thread:主要负责 React、JS 的执行,输出 App 的视图信息(结构、样式、属性等)
- Shadow Thread:根据 JS 线程的视图信息,创建出用于布局计算的 ShadowTree;(主要用到 UIManagerModule,是 RN 中非常重要的 Native Module
- Main Thread: 根据 ShadowTree 提供的完整视图信息,负责真实 Native View 的创建

- 通过 React.js 的 JSX 定义 UI 结构
- 编译阶段,通过 Babel 将 JSX 转化为 React.createElement 的形态
- 在 JS 侧,通过深度优先遍历将 JSX 编写的 UI 组件转化为 Fiber Tree 结构,每个组件节点都包含子组件、父组件和兄弟组件的引用
- JS 侧在创建 Fiber Tree 各个节点的时候会通过 Bridge 桥向 Native 侧发送对应的指令,Native 侧收到这些指令之后会创建对应的 Shadow Tree 节点,同时会生成对应的 UIViewOperation,加入到 UIViewOperationQueue 中,以供在 UI 线程进行真正的 UI 操作。JS 侧发送完一批 UI 指令之后会触发 Native 侧的 onBatchComplete 回调,进而后序遍历 ShadowTree,分别计算每个节点的宽度和高度,然后前序遍历 ShadowTree,确定每个节点的最终位置,生成相应的 UpdateLayoutOperation,加入到 UIViewOperationQueue 中
- 触发 FrameCallback,从 UIViewOperationQueue 中依次取出 UIViewOperation,生成对应的 View Tree,挂载到 RootView,进行原生 UI 渲染逻辑

如果 JavaScript 线程需要访问一些本地模块(例如蓝牙),它需要向本地线程发送消息。JS 线程将向 Bridge 发送一个序列化的 JSON 消息。Bridge 将优化此消息并将其发送到 Native 线程。消息将在 Native 线程上进行解码,最终将执行所需的本机代码
导航

- React Native 没有像 Web 浏览器那样内置的全局历史堆栈概念
- 原生堆栈导航器为应用程序提供了一种在屏幕之间转换和管理导航历史记录的方法。
- 概念上类似于 Web 浏览器处理导航状态的方式 - 您的应用程序在用户与其交互时从导航堆栈中推送和弹出项目,这会让用户看到不同的屏幕
NavigationContainer 导航容器

Screen 屏幕

- navigate- 转到另一个屏幕,找出它需要采取的行动
- reset- 擦除导航器状态并将其替换为新路线
- goBack- 关闭活动屏幕并移回堆栈
- setParams- 更改路线的参数
- dispatch- 发送一个动作对象来更新导航状态
- setOptions- 更新屏幕的选项
- isFocused- 检查屏幕是否聚焦
- addListener- 订阅来自导航器的事件更新
网络请求
在 React Native 中建立在两个 API 之上:fetch 和 XMLHttpRequest. 这两者都被设计为与浏览器 API 兼容,因此:
- Web 开发人员不必学习一种新的方式来发出网络请求
- React Native 中基于这些功能构建的库
- 直接使用 API 很常见 fetch,因为它相当强大且高级。直接使用 XMLHttpRequest 很少见,因为它复杂且低级。如果您的网络需求是高级的(多部分表单请求等),您可能希望使用一个库来抽象这些网络 API 的详细信息。
- 如果你正在寻找一个抽象层,浏览器/节点网络库喜欢 axios 并且 superagent 仍然可以在 React Native 中工作。
- Fetch 还接受一个可选的第二个参数,允许您自定义 HTTP 请求。您可能想要指定其他标头,或发出 POST 请求
useEffect(() => {
fetch('http://10.0.24.98:3000/dynamic/list')
.then(response => response.json())
.then(responseJson => {
if (responseJson.code === 200) {
setList(responseJson.data)
}
})
.catch(error => {
console.error(error)
})
console.log('进来动态页面了')
}, [])

原生能力调用的区别
WebViewJavascriptBridge
通过拦截 URL 请求来达到 native 端和 webview 端相互通信的
- native 端注册 jsb
- webview 侧创建 iframe,设置 src 为bridge_load
- native 端捕获请求,注入 jsb 初始化代码,在 window 上挂载相关对象和方法
- webview 侧调用 callHandler 方法,并在 responseCallback 上添加 callbackId: responseCallback,并修改 iframe 的 src,触发捕获
- native 收到 message,生成一个 responseCallback,并执行 native 侧注册好的方法
- native 执行完毕后,通过 webview 执行_handleMessageFromObjC 方法,取出 callback 函数,并执行

创建原生模块有两种方式
在 React Native 应用程序中直接实现原生模块
App 第一次下载打开的时候需要同意隐私协议之类的,同意进入应用不同意退出应用,退出应用这个操作前端是没办法搞的,需要 Native 端的支持(正常开发中需要安卓同学和 IOS 的同学支持)

在 RN 中“原生模块”就是一个实现了“RCTBridgeModule”协议的 Objective-C 类

实现 RCTBridgeModule 协议,你的类需要包含 RCT_EXPORT_MODULE()宏。这个宏也可以添加一个参数用来指定在 JavaScript 中访问这个模块的名字
声明要给 JavaScript 导出的方法,否则 React Native 不会导出任何方法。声明通过 RCT_EXPORT_METHOD()宏

在 js 中调用这个类的方法


在 xcode 里面调试 JS 的调用

使用 NPM 包,可以由您/其他 React Native 应用程序作为依赖项安装
https://js.coach/?collection=React+Native
跟前端中引入功能模块差不多,正式开发中需要测试双端的支持能力
注意下载包之后需要在 ios 项目中再啦一次要不然 ios 源码里面没这个

剪贴板使用场景
npm i @react-native-clipboard/clipboard



打包
有开发者账号的情况下
无开发者账号情况下
在 xcode 中 Product---》build

找到打包好的文件

创建一个 Payload 的文件夹把上图的文件复制放进去

压缩并修改扩展名为 ipa

使爱思助手签名 ipa 包

把签名成功的包拖进来安装

需要在手机端信任一下,这种办法的签名只能用 7 天,在用