第三方依赖与工具
本文档介绍 iOS-JL_OTA 仓库中示例工程(Demo)所依赖的第三方库与配套工具,涵盖 libs/ 目录下的核心 SDK XCFramework、code/JL_OTA/DFUnits.framework 通用工具库、系统框架依赖,以及三种蓝牙连接方式的依赖选型。
Purpose and Scope
本页是示例工程依赖侧的总览与索引,覆盖以下内容:
- 核心 SDK 库:
libs/目录下 5 个 XCFramework(JL_OTALib、JL_AdvParse、JL_HashPair、JL_BLEKit、JLLogHelper)的职责、必需/可选属性与导入方式。 - 通用工具库:
code/JL_OTA/DFUnits.framework中封装的工具组件(AES 加解密、CRC16 校验、GZIP 压缩、HMAC-MD5 摘要、HTTP 请求、文件/音频/网络工具等)。 - 系统框架依赖:示例工程直接使用的 Apple 系统框架(CoreBluetooth、Foundation 等)。
- 连接方式与依赖映射:原生 CoreBluetooth / JL_BLEKit / JL_Assist 三种连接方式如何影响依赖选择。
不在本页范围内(请参阅仓库中的其他页面):OTA 升级业务 API 的逐方法说明、各 Demo 工程(MiniSingleDemo、JLBleKitOTADemo、JLAssistOTADemo、code/JL_OTA)的 UI 与蓝牙管理实现细节,以及 RCSP 协议本身的解析机制。本页只回答“示例工程用了哪些第三方依赖与工具、它们各自负责什么、如何集成”。
Overview
iOS-JL_OTA 是珠海市杰理科技股份有限公司(Jieli)为杰理蓝牙设备提供的 iOS OTA 升级 SDK,基于 RCSP 协议(远程控制系统协议)。仓库同时提供三种连接方式的迷你示例与一个完整 OTA 应用示例,这些示例工程没有使用 CocoaPods/Carthage/SPM 等包管理器,而是采用直接拖入 XCFramework 二进制的方式集成依赖,这是理解本仓库依赖结构的关键前提。
从依赖的视角看,整个示例体系呈三层结构:
- 应用层:
code/下的 4 个示例工程,分别演示三种蓝牙连接方式。 - SDK/工具层:
libs/的杰理核心业务库(OTA 升级、广播解析、设备认证、可选蓝牙栈、日志)+DFUnits.framework通用工具库(源自示例工程内部自带的 DF 工具集合)。 - 系统层:CoreBluetooth、Foundation、UIKit 等 Apple 系统框架,以及设备的蓝牙硬件。
这种“业务库 + 工具库 + 系统框架”的组合,使示例工程既能用最少的第三方依赖完成 OTA 演示,又能通过 DFUnits 快速处理固件数据(校验、加解密、压缩、网络上报等)。工程结构见 README.md 第四节。
Architecture
flowchart TD
subgraph sg_Demo["示例工程层 code/"]
DemoJL["code/JL_OTA 完整示例"]
MiniSingle["MiniSingleDemo 原生 CoreBluetooth"]
JLBle["JLBleKitOTADemo JL_BLEKit"]
JLAssist["JLAssistOTADemo JL_Assist"]
end
subgraph sg_SDK["核心 SDK 库 libs/ (XCFramework)"]
OTALib["JL_OTALib.xcframework"]
AdvParse["JL_AdvParse.xcframework"]
HashPair["JL_HashPair.xcframework"]
BLEKit["JL_BLEKit.xcframework 可选"]
LogHelper["JLLogHelper.xcframework"]
end
subgraph sg_Utils["通用工具库"]
DFUnits["DFUnits.framework 工具库"]
end
subgraph sg_System["系统框架层"]
CB["CoreBluetooth"]
Fnd["Foundation / UIKit"]
end
DemoJL --> OTALib
DemoJL --> AdvParse
DemoJL --> HashPair
DemoJL --> LogHelper
DemoJL --> DFUnits
MiniSingle --> OTALib
MiniSingle --> CB
JLBle --> OTALib
JLBle --> BLEKit
JLAssist --> OTALib
OTALib --> CB
BLEKit --> CB
DFUnits --> Fnd
图例说明:
- 示例工程层中的 4 个工程是依赖的消费方。
code/JL_OTA完整示例同时引入全部核心库与 DFUnits 工具库;三个 MiniDemo 只引入 OTA 业务库,并按连接方式决定是否引入JL_BLEKit。 - 核心 SDK 库以 XCFramework 形式发布,是二进制闭源依赖,开发者通过
Embed & Sign集成。JL_OTALib是所有示例的公共依赖,其底层仍依赖系统 CoreBluetooth 完成 GATT 通信;JL_BLEKit是对 CoreBluetooth 的一层封装,仅在JLBleKitOTADemo中被直接使用。 - DFUnits.framework 是随
code/JL_OTA示例一起提供的 Objective-C 工具库(源码目录位于code/JL_OTA/DFUnits.framework/Headers/),负责固件数据的底层加工(CRC16 校验、AES 加解密、GZIP 压缩、HMAC-MD5 等),与业务 SDK 解耦。 - 系统框架层提供蓝牙与基础能力。无论选择哪种连接方式,最终都落在 CoreBluetooth 之上;
JL_Assist方式则允许把外部既有的蓝牙层桥接进来,此时 CoreBluetooth 由外部蓝牙层持有。
核心 SDK 库(libs/)
libs/ 目录存放以 XCFramework 格式发布的杰理核心 SDK 库,支持 iOS 12.0+ 与 Xcode 14.0+(见 README.md 运行环境)。根据 README.md 配置说明,依赖分为必需与可选两类:
| 库名 | 类别 | 职责 |
|---|---|---|
JL_OTALib.xcframework | 必需 | OTA 升级业务库,封装 RCSP 协议指令(cmdTargetFeature、cmdOTAData 等)与升级状态机,是所有示例的公共依赖 |
JL_AdvParse.xcframework | 必需 | 杰理蓝牙设备广播包解析库,扫描阶段解析设备广播数据 |
JL_HashPair.xcframework | 必需 | 设备认证业务库,实现 Hash 配对认证 |
JLLogHelper.xcframework | 必需 | 日志打印收集库,统一日志输出与收集 |
JL_BLEKit.xcframework | 可选 | 蓝牙连接核心库,封装扫描/连接/服务发现/分包发送等蓝牙细节;仅在使用杰理集成蓝牙栈时导入 |
设计意图:将升级业务(OTALib)、广播解析(AdvParse)、安全认证(HashPair)、蓝牙栈(BLEKit)、可观测性(LogHelper)拆分为独立二进制,让开发者按需组合——例如已有自有蓝牙层时可不引入 BLEKit,从而减少依赖面与二进制体积。
DFUnits.framework 通用工具库
code/JL_OTA/DFUnits.framework/Headers/ 下提供了由示例工程携带的 Objective-C 工具组件(头文件列表见仓库源码)。这些工具与业务 SDK 解耦,负责 OTA 场景中常见的底层数据处理:
| 头文件 | 工具职责 |
|---|---|
AESx.h | AES 加解密,用于固件/数据加解密 |
DFCrc16.h | CRC16 校验(独立计算 / 累加计算 / 重置),用于固件数据完整性校验 |
DFGzip.h | GZIP 压缩/解压,用于固件或日志数据的压缩传输 |
DFHmacMD5.h | HMAC-MD5 摘要计算,用于数据签名/鉴权 |
DFHttp.h / DFHttp1.h | HTTP 请求封装,用于固件下载、日志上报等网络操作 |
DFFile.h | 文件读写工具,管理本地固件文件 |
DFAudio.h / DFNetPlayer.h | 音频播放与网络音频播放 |
DFImage.h | 图片处理工具 |
DFPing.h | 网络连通性探测(ping) |
DFNotice.h | 通知/事件分发工具 |
DFSort.h | 排序工具 |
DFAction.h | 动作/命令封装 |
DFContacts.h | 通讯录访问工具 |
DFLabel.h / DFFadeLabel.h / DFCircleTextView.h | 自定义 UI 控件(标签、渐隐标签、圆形文本视图) |
DFRing.h | 铃声/提示音工具 |
说明:除
DFCrc16.h外,其余头文件仅按仓库中的文件清单列出职责定位;若需逐个组件的完整 API,请直接阅读对应头文件源码。
其中 DFCrc16 是 OTA 升级流程中高频使用的校验组件,其完整接口见下文「API Reference」。CRC16 计算用于验证固件分片/文件在传输过程中的完整性,这是 BLE 分包传输场景下保证升级可靠性的基础手段。
三种连接方式与依赖选型
示例工程通过三种连接方式演示同一套 OTA 能力,这是理解依赖选型的核心。根据 README.md 连接方式选择:
| 连接方式 | 适用场景 | Demo 工程 | 依赖差异 |
|---|---|---|---|
| 原生 CoreBluetooth | 完全掌控 BLE 扫描、连接、服务与分包发送 | code/MiniDemo/MiniSingleDemo/ | 只依赖 JL_OTALib + 系统 CoreBluetooth |
| JL_BLEKit | 快速集成、减少蓝牙细节处理 | code/MiniDemo/JLBleKitOTADemo/ | 额外依赖 JL_BLEKit.xcframework |
| JL_Assist 自定义 | 已有外部蓝牙管控,或需桥接到既有蓝牙层 | code/MiniDemo/JLAssistOTADemo/ | 不依赖 BLEKit,由外部蓝牙层接管底层通信 |
完整示例 code/JL_OTA 则同时保留了三套蓝牙管理实现目录(BleManager、BleByAssist、SDKBleManager),对应上述三种方式(见 README.md 工程结构)。
flowchart LR
subgraph sg_Choose["连接方式选择"]
Q{"已有蓝牙层?"}
Q -->|"否,且想快速集成"| B["JL_BLEKit 方式"]
Q -->|"否,且要完全掌控"| C["原生 CoreBluetooth 方式"]
Q -->|"是,外部蓝牙管控"| A["JL_Assist 方式"]
end
A --> D["依赖: JL_OTALib + 外部蓝牙层"]
B --> E["依赖: JL_OTALib + JL_BLEKit"]
C --> F["依赖: JL_OTALib + CoreBluetooth"]
D --> G["统一调用 OTA 业务 API"]
E --> G
F --> G
设计意图:JL_OTALib 面向 RCSP 协议业务,不关心底层蓝牙由谁提供。三种连接方式通过不同的适配层(原生 / BLEKit / Assist 桥接)向业务层提供统一的数据通道,使得 OTA 升级流程代码可以完全复用,仅替换连接适配层即可。
核心调用流程
根据 README.md 快速集成步骤,一次完整的 OTA 升级在依赖层之间的协作顺序如下:
sequenceDiagram
participant App as 示例应用
participant SDK as JL_OTALib
participant BLE as 蓝牙层 (CoreBluetooth / JL_BLEKit / JL_Assist)
participant Adv as JL_AdvParse
participant Dev as 杰理蓝牙设备
App->>BLE: 扫描并连接设备
BLE-->>App: 设备已连接
App->>SDK: 订阅设备 + noteEntityConnected
SDK->>SDK: cmdTargetFeature 查询设备能力
SDK-->>App: 能力回包
App->>SDK: cmdOTAData(data) 发送固件数据
SDK->>BLE: 分包写入 GATT 特征
BLE->>Dev: 数据包
Dev-->>BLE: 应答
BLE-->>SDK: otaDataSend 进度回调
SDK-->>App: otaUpgradeResult 升级结果
App->>BLE: 断开 (noteEntityDisconnected)
流程要点:
- 扫描连接:应用层通过选定的蓝牙层(原生 CoreBluetooth / JL_BLEKit / JL_Assist)扫描设备;使用
JL_AdvParse解析杰理设备广播包以识别设备。 - 能力探测:连接并订阅后,
noteEntityConnected通知触发cmdTargetFeature查询设备支持的特性,决定升级策略(单备份/双备份、强制升级等)。 - 数据下发:
cmdOTAData(data)将固件数据交给JL_OTALib,SDK 内部按 GATT 分包写入特征;每包数据的完整性依赖 DFUnits 类工具(如 CRC16)校验。 - 进度与结果:
otaDataSend回调上报发送进度,otaUpgradeResult上报最终升级结果;断开时通过noteEntityDisconnected清理状态。
该流程中,依赖层各自职责清晰:JL_OTALib 管协议与状态机、蓝牙层管字节传输、JL_AdvParse 管设备识别、DFUnits 管数据加工,应用层只编排 UI 与业务流程。
使用示例
以下示例均直接取自仓库源码,展示第三方依赖与工具的实际使用方式。
1. DFUnits 工具库:CRC16 校验组件接口
DFCrc16.h 是 DFUnits 框架中负责 CRC16 校验的类,提供“单次计算、累加计算、重置”三种能力,适配固件分片校验场景(分片传输时用累加模式,独立文件校验时用单次模式):
@interface DFCrc16 : NSObject
/**
* 单独Crc16值.
*/
+(uint16_t)didCrc16:(uint8_t*)pt
Length:(uint16_t)len;
/**
* 累加Crc16值.
*/
+(uint16_t)didCrc16All:(uint8_t*)pt
Length:(uint16_t)len
CrcValue:(uint16_t)value;
/**
* 清除Crc值.
*/
+(void)didResetCrc;
@end
Source: DFCrc16.h
使用要点:didCrc16:Length: 对一段内存做独立 CRC16 计算;didCrc16All:Length:CrcValue: 把上一段的 CRC 结果作为 CrcValue 传入,实现跨分片累加校验;didResetCrc 用于开始新一轮校验前复位内部状态。
2. 依赖集成:XCFramework 导入与核心调用序列
仓库 README.md 给出第三方依赖的标准集成步骤与调用序列,是所有 Demo 的共同基线:
1. 集成 JL_OTALib.xcframework、JL_AdvParse.xcframework、JL_HashPair.xcframework、
JLLogHelper.xcframework 并设置 Embed & Sign
2. 配置权限:Privacy - Bluetooth Peripheral/Always Usage Description
3. 核心调用流程:设备连接+订阅 → noteEntityConnected → cmdTargetFeature →
cmdOTAData(data) → 委托回调 otaUpgradeResult、otaDataSend →
断开时 noteEntityDisconnected
Source: README.md
3. 依赖目录结构总览
仓库把示例源码、SDK 二进制与文档按目录隔离,便于开发者识别“哪些是第三方依赖、哪些是示例代码”:
iOS-JL_OTA/
├── code/ # 示例程序源码(消费依赖)
│ ├── MiniDemo/ # 迷你示例工程(三种连接方式)
│ │ ├── MiniSingleDemo/ # 原生 CoreBluetooth 连接示例
│ │ ├── JLBleKitOTADemo/ # JL_BLEKit 连接示例
│ │ └── JLAssistOTADemo/ # JL_Assist 自定义连接示例
│ └── JL_OTA/ # 完整 OTA 应用示例(含 DFUnits.framework)
│ ├── BleManager/ # 自定义蓝牙连接实现
│ ├── BleByAssist/ # JL_Assist 蓝牙连接实现
│ ├── SDKBleManager/ # JL_BLEKit 蓝牙连接实现
│ └── Views/ # UI 视图
├── libs/ # 核心 SDK 库 (XCFramework 格式,第三方依赖)
│ ├── JL_OTALib.xcframework # OTA 升级业务库
│ ├── JL_AdvParse.xcframework # 广播包解析库
│ ├── JL_HashPair.xcframework # 设备认证库
│ ├── JL_BLEKit.xcframework # 蓝牙连接核心库(可选)
│ └── JLLogHelper.xcframework # 日志辅助库
└── doc/ # 文档资源
Source: README.md
Configuration Options
示例工程对第三方依赖的配置主要集中在 Xcode 工程设置 与 Info.plist 权限 两个层面(依据 README.md 配置说明):
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| 框架导入方式 | Xcode 设置 | 手动拖入 | 需导入 JL_OTALib、JL_AdvParse、JL_HashPair、JLLogHelper 并设置 Embed & Sign |
| 可选框架 | Xcode 设置 | 不导入 | JL_BLEKit.xcframework 仅在使用杰理集成蓝牙栈时导入 |
Privacy - Bluetooth Peripheral Usage Description | Info.plist | 无(必填) | BLE 外设访问权限描述,缺省会导致蓝牙授权弹窗无法出现 |
Privacy - Bluetooth Always Usage Description | Info.plist | 无(建议) | 后台/持续使用蓝牙场景的权限描述 |
| 最小部署版本 | Xcode 设置 | iOS 12.0+ | SDK 与示例的最低系统要求 |
| 工具链版本 | Xcode 设置 | Xcode 14.0+ | 构建示例工程所需的 Xcode 版本 |
| 语言 | 工程设置 | Objective-C / Swift | SDK 提供完整的 ObjC 与 Swift API 支持 |
设计意图:Embed & Sign 确保 XCFramework 二进制在真机与模拟器上都能正确签名与加载;蓝牙权限描述是 iOS 系统强制的隐私合规要求,缺省时系统直接拒绝访问蓝牙,所有依赖 CoreBluetooth 的库(OTALib、BLEKit)都会失效。
API Reference
DFCrc16(DFUnits.framework)
DFUnits 工具库中用于 CRC16 校验的类,为固件数据传输提供完整性校验能力。
+ (uint16_t)didCrc16:(uint8_t*)pt Length:(uint16_t)len
对一段内存计算独立的 CRC16 值。
参数:
pt(uint8_t*):待校验数据缓冲区指针len(uint16_t):待校验数据长度(字节)
返回: uint16_t 类型的 CRC16 校验值。
+ (uint16_t)didCrc16All:(uint8_t*)pt Length:(uint16_t)len CrcValue:(uint16_t)value
累加计算 CRC16,将前一段数据的 CRC 结果作为 value 传入,用于固件分片连续传输场景。
参数:
pt(uint8_t*):当前分片数据缓冲区指针len(uint16_t):当前分片长度value(uint16_t):前一分片计算出的 CRC16 值(首片通常传 0 或复位后的初始值)
返回: 累加后的 uint16_t CRC16 校验值。
+ (void)didResetCrc
清除/复位 CRC 内部状态,在开始新一轮校验前调用。
以上接口签名均来自 DFCrc16.h。其余 DFUnits 组件(AES、GZIP、HMAC-MD5、HTTP 等)与
libs/下各 XCFramework 的接口为二进制闭源或需查阅对应头文件/文档中心,本页不逐一罗列。
Failure Modes、边界与并发
依据仓库现有证据(README 集成说明 + DFUnits 源码),以下是依赖层相关的典型问题与规避方式:
| 场景 | 风险 | 处理建议 |
|---|---|---|
| 蓝牙权限描述缺失 | 系统拒绝蓝牙授权,OTALib/BLEKit 无法工作 | 在 Info.plist 配置 Privacy - Bluetooth Peripheral/Always Usage Description |
XCFramework 未设置 Embed & Sign | 真机运行崩溃(dyld 找不到框架) | 对导入的 4 个必需框架均启用 Embed & Sign |
| 缺少可选框架却使用 JL_BLEKit 方式 | 链接错误或运行期 unrecognized selector | 使用 JLBleKitOTADemo 方式时务必导入 JL_BLEKit.xcframework |
| 固件分片传输丢包/错序 | CRC16 校验失败、升级中断 | 使用 DFCrc16 的累加接口逐片校验,失败分片重发 |
| 升级中断开连接 | 升级状态机卡死 | 按 noteEntityDisconnected 通知清理状态,必要时触发 SDK 的回连机制 |
| 多线程数据发送 | BLE 写特征并发导致 GATT 层异常 | 将 cmdOTAData 的数据下发限制在串行队列,等待 otaDataSend 回调后再发下一包 |
并发注意点:JL_OTALib 的 OTA 数据下发与 DFUnits 的校验计算通常运行在后台队列;DFCrc16 为类方法、内部无共享可变状态(除 didResetCrc 涉及内部复位),多线程场景下建议对同一设备的校验流程串行化,避免校验值与数据流错位。
性能与运维注意事项
- 包管理策略:本仓库不使用 CocoaPods/Carthage/SPM,依赖以 XCFramework 二进制直接随仓库分发。升级 SDK 时整体替换
libs/目录并重新Embed & Sign即可,无需解析依赖树,但需注意 XCFramework 的架构支持(模拟器/真机 slice)与 Xcode 14.0+ 的兼容性。 - 日志可观测性:
JLLogHelper.xcframework负责日志打印收集,排查 OTA 问题时开启其日志并配合DFFile落盘,可还原升级失败现场。 - 固件数据加工成本:CRC16/AES/GZIP 等 DFUnits 计算在大固件场景(数 MB 固件分片)下会占用 CPU,建议在后台队列执行并避免在主线程调用。
- 网络依赖:
DFHttp/DFHttp1用于固件下载与日志上报,生产环境需关注超时与重试策略(源码中未显式配置,需按业务自行设置)。
Extension Points
- 连接适配层:
code/JL_OTA中的BleManager(原生)、SDKBleManager(JL_BLEKit)、BleByAssist(JL_Assist)是三套可替换的蓝牙适配实现,向业务层提供统一数据通道。开发者可仿照JLAssistOTADemo把自有蓝牙层桥接为 JL_Assist 方式,不改动 OTA 业务代码。 - 工具库扩展:DFUnits 是独立于 SDK 的 Objective-C 工具集,可在示例工程中按需新增工具类(如新的校验/加密算法),不影响
libs/二进制。 - 能力探测分支:
cmdTargetFeature返回的设备能力决定升级策略,应用层可据此扩展 UI 分支(单备份/双备份/强制升级提示)。
Related Links
- README.md(仓库总览、工程结构、配置说明)
- DFCrc16.h(DFUnits 工具库源码)
- DFUnits.framework 头文件目录
- 各示例工程的连接方式说明:请参阅 Demo 相关目录(
code/MiniDemo/、code/JL_OTA/)对应的页面 - 杰理文档中心:https://doc.zh-jieli.com/Apps/iOS/ota/zh-cn/master/index.html