迷你示例工程
本页介绍仓库 code/MiniDemo 目录下的三个迷你 Swift 示例工程(JLAssistOTADemo、JLBleKitOTADemo、MiniSingleDemo),它们以最小可运行工程的形式演示如何在 iOS App 中接入杰理(Jieli)BLE OTA 升级流程,并说明其中内嵌的 JL_AdvParse 广播解析框架的组成。
Purpose and Scope
本页覆盖 code/MiniDemo 下的迷你示例工程集合:
- 三个工程的定位差异与公共骨架(AppDelegate / SceneDelegate / ViewController / BleManager / OTAActionManager 五个 Swift 文件);
- JLAssistOTADemo 内嵌的 JL_AdvParse.xcframework 及其对外头文件(广播解析 API 表面);
- 迷你工程与主工程
code/JL_OTA的关系。
以下内容属于其他目录页面的职责,本页不做展开:
- 完整 OTA 主工程(
code/JL_OTA,含 Pods 依赖与完整 UI)——见主工程相关页面; - JL SDK 的完整 API 文档与升级协议细节——见 SDK 文档页面。
说明:本次文档写作受源码探索预算限制,仅核验了工程目录结构、文件清单与框架头文件清单;各 Swift 文件的具体实现代码未能逐行读取,文中涉及实现细节之处均明确标注为推断或待读源码,未做任何虚构。
Overview
code/MiniDemo 目录下并列放置了三个独立的 Xcode 工程,目标都是用最少的代码演示一次完整的 BLE OTA 升级,便于二次开发时复制粘贴、对照集成:
| 工程 | 目录 | 特征 |
|---|---|---|
| JLAssistOTADemo | code/MiniDemo/JLAssistOTADemo | 内嵌预编译的 JL_AdvParse.xcframework,集成 JL_Assist 系列能力,演示广播解析 + OTA |
| JLBleKitOTADemo | code/MiniDemo/JLBleKitOTADemo | 面向 JL_BleKit 体系的 OTA 演示 |
| MiniSingleDemo | code/MiniDemo/MiniSingleDemo | 最小化单工程演示,结构与另外两个一致,便于独立编译验证 |
三个工程使用相同的五个 Swift 文件骨架(AppDelegate.swift、SceneDelegate.swift、ViewController.swift、BleManager.swift、OTAActionManager.swift),说明它们是同一套演示逻辑在三种 SDK/集成形态下的复刻。这种"一骨架、多工程"的组织方式,让使用者可以只关注自己将要使用的 SDK 形态,而不用在大工程里做减法。
核心概念:
- BleManager:负责 BLE 扫描、连接与状态回调的封装;
- OTAActionManager:负责 OTA 升级动作的发起、进度与结果管理;
- ViewController:唯一界面,串联蓝牙连接与 OTA 动作,展示升级状态;
- JL_AdvParse:解析设备广播包(Advertising Data)的预编译框架,按设备形态(耳机、音箱、声卡、TWS、手表、充电仓等)提供解析类。
Architecture
下图展示 code/MiniDemo 下三个迷你工程的并列关系、公共骨架,以及 JLAssistOTADemo 对内嵌框架的依赖:
flowchart TD
subgraph sg_MiniDemo["code/MiniDemo 迷你示例工程"]
subgraph sg_Assist["JLAssistOTADemo"]
AssistFiles["AppDelegate / SceneDelegate<br/>ViewController / BleManager / OTAActionManager"]
AssistFramework["JL_AdvParse.xcframework<br/>(ios-arm64 + ios-arm64_x86_64-simulator)"]
end
subgraph sg_BleKit["JLBleKitOTADemo"]
BleKitFiles["AppDelegate / SceneDelegate<br/>ViewController / BleManager / OTAActionManager"]
end
subgraph sg_Single["MiniSingleDemo"]
SingleFiles["AppDelegate / SceneDelegate<br/>ViewController / BleManager / OTAActionManager"]
end
end
subgraph sg_Main["主工程 code/JL_OTA"]
MainProject["JL_OTA.xcodeproj<br/>Pods: AFNetworking / Bugly / Colours / GCDWebServer / Masonry"]
end
AssistFiles -->|"依赖"| AssistFramework
AssistFiles -.->|"同源演示逻辑"| BleKitFiles
AssistFiles -.->|"同源演示逻辑"| SingleFiles
架构解读:
- 三个工程并列且互相独立,每个都是可单独打开、编译运行的 Xcode 工程;
- JLAssistOTADemo 是唯一内嵌二进制框架的工程——
JL_AdvParse.xcframework位于工程目录下,包含ios-arm64与ios-arm64_x86_64-simulator两个平台切片,真机与模拟器均可链接; - 演示逻辑同源:三个工程共享同名同职责的五个 Swift 文件,便于横向对比同一 OTA 流程在不同 SDK 形态下的接入差异;
- 与主工程的关系:
code/JL_OTA是功能完整的主工程(引入 AFNetworking、Bugly、Colours、GCDWebServer、Masonry 等 Pods),迷你工程是其"最小可运行"的裁剪版,适合作为集成的起点模板。
工程清单与定位
code/MiniDemo 目录下三个工程的文件布局(已核验):
code/MiniDemo/
├── JLAssistOTADemo/
│ ├── JL_AdvParse.xcframework/ # 预编译广播解析框架(双平台切片)
│ │ ├── Info.plist
│ │ ├── ios-arm64_x86_64-simulator/JL_AdvParse.framework/
│ │ │ ├── Headers/ # 9 个公开头文件
│ │ │ ├── Modules/module.modulemap
│ │ │ └── JL_AdvParse # 模拟器二进制
│ │ └── ios-arm64/JL_AdvParse.framework/
│ │ ├── Headers/ # 9 个公开头文件
│ │ ├── Modules/module.modulemap
│ │ └── JL_AdvParse # 真机二进制
│ └── JLAssistOTADemo/
│ ├── AppDelegate.swift
│ ├── SceneDelegate.swift
│ ├── ViewController.swift
│ ├── BleManager.swift
│ └── OTAActionManager.swift
├── JLBleKitOTADemo/
│ └── JLBleKitOTADemo/ # 同骨架五个 Swift 文件
└── MiniSingleDemo/
└── MiniSingleDemo/ # 同骨架五个 Swift 文件
Source: code/MiniDemo 目录结构
三个工程的定位差异(工程名与依赖形态为依据,属命名推断):
| 工程 | 集成形态 | 用途 |
|---|---|---|
| JLAssistOTADemo | JL_Assist 能力 + JL_AdvParse.xcframework | 演示"广播解析 + OTA"完整链路,工程自带预编译框架,开箱即用 |
| JLBleKitOTADemo | JL_BleKit 体系 | 演示基于 BleKit 的 OTA 接入,不内嵌额外框架 |
| MiniSingleDemo | 最小自包含 | 剔除外部框架依赖后的最小演示,便于快速跑通流程 |
公共工程骨架
三个工程均以 SwiftUI/UIKit 生命周期入口 + 单页面 + 两个管理类构成,职责划分如下(基于文件命名与工程惯例推断,具体实现以源码为准):
| 文件 | 职责 |
|---|---|
AppDelegate.swift | App 启动入口,负责应用级初始化与生命周期回调 |
SceneDelegate.swift | 场景生命周期管理,创建窗口与根视图 |
ViewController.swift | 唯一界面:扫描/连接按钮、升级按钮、状态展示 |
BleManager.swift | BLE 核心封装:扫描外设、建立连接、断开与状态回调 |
OTAActionManager.swift | OTA 动作封装:发起升级、下发数据、进度与结果回调 |
Source: JLAssistOTADemo/ViewController.swift 等五个文件
设计意图:把"界面"(ViewController)、"连接"(BleManager)、"升级"(OTAActionManager)三者解耦,使用者可以在不改动界面的前提下替换蓝牙管理实现,或在不动蓝牙层的前提下替换 OTA 协议实现——这与主工程 code/JL_OTA 的分层思想一致,只是去掉了业务复杂度。
JL_AdvParse 广播解析框架
JLAssistOTADemo 内嵌的 JL_AdvParse.xcframework 是预编译二进制框架,对外暴露统一入口 JL_AdvParse.h / JLAdvParse.h,并按设备形态拆分解析类。公开头文件清单(已核验,位于 ios-arm64/JL_AdvParse.framework/Headers/):
| 头文件 | 解析对象(按文件名推断) |
|---|---|
JL_AdvParse.h | 框架统一入口头文件 |
JLAdvParse.h | 广播解析主接口 |
JLEarphoneAdv.h | 耳机(Earphone)广播包解析 |
JLTwsAdv.h | TWS 耳机广播包解析 |
JLSoundBoxAdv.h | 音箱(SoundBox)广播包解析 |
JLSoundCardAdv.h | 声卡(SoundCard)广播包解析 |
JLWatchAdv.h | 手表(Watch)广播包解析 |
JLChargingBoxAdv.h | 充电仓(ChargingBox)广播包解析 |
JLDevicesAdv.h | 通用设备广播包解析 |
JLOtaAdv.h | OTA 相关广播字段解析 |
Source: JL_AdvParse.h 及同目录 Headers 清单
设计意图:杰理生态设备种类多(耳机、TWS、音箱、声卡、手表、充电仓),广播包字段各异。把解析逻辑放进独立预编译框架,并按设备形态拆分为多个头文件,可以让 App 只 import 自己需要的解析类,避免一次性引入全部解析代码;同时 ios-arm64 与 ios-arm64_x86_64-simulator 双切片保证真机与模拟器都能调试。
与主工程的关系
主工程 code/JL_OTA(project.pbxproj)是功能完整的 OTA 升级 App,依赖 Pods(AFNetworking、Bugly、Colours、GCDWebServer、Masonry 等)。迷你工程与它的关系:
- 同源分层:迷你工程中的 BleManager / OTAActionManager 命名与主工程能力对应,是主工程核心链路的精简复刻;
- 独立可跑:迷你工程不依赖 Pods,单独打开即可编译运行,降低上手门槛;
- 互补定位:需要完整 UI、崩溃上报(Bugly)、本地 Web 服务(GCDWebServer)等能力时回到主工程;只需要最小集成参考时看迷你工程。
仓库根目录的 README.md 与 README_EN.md 提供了工程总览与使用入口。
Core Flow
基于三个工程共享的文件骨架,迷你示例的典型 OTA 调用链如下(参与方均为真实文件;箭头顺序依据文件职责与 OTA 常规流程推断,具体实现以源码为准):
sequenceDiagram
participant App as AppDelegate/SceneDelegate
participant VC as ViewController
participant BM as BleManager
participant OM as OTAActionManager
participant Dev as BLE 设备
App->>VC: 启动并展示主界面
VC->>BM: 开始扫描 / 发起连接
BM->>Dev: CoreBluetooth 连接
Dev-->>BM: 连接状态 / 广播数据
BM-->>VC: 状态回调(已连接 / 失败)
VC->>OM: 触发 OTA 升级动作
OM->>Dev: 下发升级数据与指令
Dev-->>OM: 进度 / 结果回调
OM-->>VC: 刷新升级状态 UI
流程要点:
- 启动:AppDelegate/SceneDelegate 完成 App 初始化,创建 ViewController;
- 连接:ViewController 调用 BleManager 扫描并连接目标设备,BleManager 屏蔽 CoreBluetooth 细节,以回调形式通知界面;
- 升级:连接成功后,ViewController 调用 OTAActionManager 发起升级,OTAActionManager 负责数据下发与进度收集;
- 收尾:升级进度/结果经 OTAActionManager 回传界面刷新展示;JLAssistOTADemo 中,广播数据(含 OTA 状态字段)由 JL_AdvParse 解析后供界面使用。
flowchart LR
A["BLE 广播包"] --> B["JL_AdvParse<br/>(JLEarphoneAdv / JLTwsAdv / JLSoundBoxAdv /<br/>JLSoundCardAdv / JLWatchAdv / JLChargingBoxAdv / JLDevicesAdv / JLOtaAdv)"]
B --> C["结构化设备信息"]
C --> D["ViewController 展示 / 决定是否可升级"]
第二条链路展示了 JLAssistOTADemo 中广播解析的职责边界:原始广播字节 → 框架按设备形态解析 → 结构化信息 → UI 使用。这套解析与 OTA 升级动作(OTAActionManager)解耦,解析结果只用于展示与可升级性判断。
Usage Examples
示例一:工程目录即最小集成模板
迷你工程的意义在于"复制即用"。以下为 MiniSingleDemo 工程文件清单(已核验),集成时把这五个文件拖入自己的工程,再按需替换 SDK 依赖即可:
MiniSingleDemo/MiniSingleDemo/
├── AppDelegate.swift
├── SceneDelegate.swift
├── ViewController.swift
├── BleManager.swift
└── OTAActionManager.swift
Source: MiniSingleDemo 工程目录
示例二:引入 JL_AdvParse 广播解析
JLAssistOTADemo 的集成方式是在工程目录下放置 JL_AdvParse.xcframework 并在工程中链接。框架通过 modulemap 暴露为可 import 的模块,使用时按设备形态引入对应头文件,例如耳机类设备引入 JLEarphoneAdv.h、音箱类设备引入 JLSoundBoxAdv.h:
JLAssistOTADemo/JL_AdvParse.xcframework/
├── ios-arm64/JL_AdvParse.framework/Headers/
│ ├── JL_AdvParse.h # 统一入口
│ ├── JLAdvParse.h # 主解析接口
│ ├── JLEarphoneAdv.h # 耳机解析
│ ├── JLTwsAdv.h # TWS 解析
│ ├── JLSoundBoxAdv.h # 音箱解析
│ ├── JLSoundCardAdv.h # 声卡解析
│ ├── JLWatchAdv.h # 手表解析
│ ├── JLChargingBoxAdv.h # 充电仓解析
│ ├── JLDevicesAdv.h # 通用设备解析
│ └── JLOtaAdv.h # OTA 字段解析
└── ios-arm64_x86_64-simulator/JL_AdvParse.framework/Headers/ # 与真机切片一致
Source: JL_AdvParse 头文件清单
注:本次文档写作受源码探索预算限制,未能读取 Swift 源码正文,故不提供未经核验的代码片段;具体 API 调用示例请直接阅读上述源文件。
Configuration Options
迷你工程刻意保持"零配置",以降低集成门槛。基于已核验的目录结构,工程层面的可选项如下:
| 配置项 | 取值 | 默认/说明 |
|---|---|---|
| 工程形态 | JLAssistOTADemo / JLBleKitOTADemo / MiniSingleDemo | 按所需 SDK 形态选择工程 |
| 平台切片 | ios-arm64 / ios-arm64_x86_64-simulator | JL_AdvParse.xcframework 已同时包含,无需配置 |
| 外部依赖 | Pods 仅主工程使用 | 迷你工程不依赖 CocoaPods,开箱即编译 |
说明:BleManager/OTAActionManager 内部的可调参数(如扫描超时、升级重试次数)位于各 Swift 文件中,本页受预算限制未能读取核验,请以源文件为准。
API Reference
本次源码探索核验到的 API 表面为 JL_AdvParse 框架对外头文件(二进制框架的公开接口入口)。各头文件的具体方法签名未在本页读取,以下为头文件级 API 表面:
| 头文件 | 角色 | 使用场景 |
|---|---|---|
JL_AdvParse.h | 框架统一头文件 | 工程 import 该框架时的总入口 |
JLAdvParse.h | 广播解析主接口 | 解析入口,按设备类型分发 |
JLEarphoneAdv.h | 耳机广播解析 | 耳机类设备广播包解析 |
JLTwsAdv.h | TWS 广播解析 | TWS 对耳广播包解析 |
JLSoundBoxAdv.h | 音箱广播解析 | 音箱类设备广播包解析 |
JLSoundCardAdv.h | 声卡广播解析 | 声卡类设备广播包解析 |
JLWatchAdv.h | 手表广播解析 | 手表类设备广播包解析 |
JLChargingBoxAdv.h | 充电仓广播解析 | 充电仓广播包解析 |
JLDevicesAdv.h | 通用设备广播解析 | 其他/通用设备解析 |
JLOtaAdv.h | OTA 广播字段解析 | 提取广播中的 OTA 状态/版本字段 |
Throws / 错误处理:框架头文件未在本页读取,错误类型(如广播包长度不足、校验失败等)无法在此列出;BleManager 与 OTAActionManager 的异常处理逻辑位于对应 Swift 文件中,请在集成前通读源码。
Failure Modes, Edge Cases & Concurrency
以下内容基于工程结构与 OTA 场景的通用工程实践给出风险清单;各工程源码中的具体容错实现未能在本次探索预算内读取,标注为"待核验":
| 风险场景 | 涉及组件 | 说明 |
|---|---|---|
| BLE 连接失败/超时 | BleManager | 扫描不到设备、连接被拒等;建议集成时核对 BleManager 的回调与重试策略(待核验) |
| 连接中途断开 | BleManager / OTAActionManager | 升级中掉线需中止并复位状态机,避免半升级状态(待核验) |
| 广播包解析失败 | JL_AdvParse | 广播数据可能不完整或设备型号不匹配,解析类应返回失败而非崩溃(待核验) |
| OTA 升级中断 | OTAActionManager | 电量不足、传输超时等;需确认是否有失败回调与恢复路径(待核验) |
| 并发回调 | BleManager / OTAActionManager | 蓝牙回调与 UI 刷新分属不同线程,需确认回调是否回主线程更新 UI(待核验) |
并发与线程安全:iOS CoreBluetooth 回调默认不在主线程,迷你工程若未做线程切换,UI 更新可能产生竞态;这是集成时必须重点核对的点(以各工程 BleManager.swift 实现为准)。
Performance & Operational Considerations
- 预编译框架双切片:JL_AdvParse.xcframework 同时提供
ios-arm64(真机)与ios-arm64_x86_64-simulator(模拟器)二进制,开发者无需为不同运行环境切换依赖,调试与发布共用同一集成方式; - 按需解析:框架按设备形态拆分头文件,App 只链接自己需要的解析类,可减少不必要的符号加载;
- 最小化工程:迷你工程不引入 Pods,编译链路短、启动快,适合作为 CI 冒烟测试或集成验证的最小载体;
- 升级性能:OTA 数据下发吞吐与分包策略由 OTAActionManager 与 SDK 内部决定,性能调优参数见对应 SDK 文档(本页未覆盖)。
Extension Points
迷你工程作为"最小可运行模板",其扩展点体现在结构与职责边界上:
- 替换蓝牙层:保持 ViewController 与 OTAActionManager 不变,重写 BleManager 即可接入自己的扫描/连接策略(如指定设备过滤、自动重连);
- 替换升级动作:保持界面与连接层不变,替换 OTAActionManager 内部实现即可切换升级协议版本或升级策略;
- 扩充设备形态:在 JLAssistOTADemo 中新增设备类型时,可在 JL_AdvParse 框架侧按头文件拆分模式(如
JLEarphoneAdv.h)增加对应的解析类,界面侧通过JLDevicesAdv或具体设备类分派; - 向主工程演进:当演示逻辑验证通过后,可把 BleManager / OTAActionManager 抽取到主工程
code/JL_OTA使用,迷你工程与主工程共用同一套职责分层。
Tests
仓库中未发现与迷你工程对应的独立测试目录(本次探索仅见三个工程的 Swift 源文件与 xcframework)。迷你工程本身即充当可手动验证的冒烟测试载体:编译运行 → 连接真机设备 → 观察升级流程。如需自动化测试,建议围绕 OTAActionManager 的输入(升级文件、设备信息)与输出(进度、结果回调)编写单元测试,但现有仓库未提供现成测试用例。