杰理 SDK 文档中心
首页
首页
  • 项目概览

    • 项目概述与功能特性
    • 工程结构与运行环境
  • 快速开始

    • SDK 集成步骤
    • 连接方式选择指南
  • 核心 SDK 架构

    • SDK 框架组成
    • JL_OTAManager 升级管理 API
    • 设备认证与广播解析
  • 蓝牙连接与设备发现

    • 设备扫描与广播发现
    • 原生 CoreBluetooth 连接
    • JL_BLEKit SDK 连接
    • JL_Assist 自定义连接
    • GATT Over BR/EDR 经典蓝牙升级
  • OTA 升级工作流

    • 标准升级流程
    • 自动化测试与批量升级
    • 广播音箱升级
    • 升级文件管理
  • 示例工程

    • 完整示例应用
    • 迷你示例工程
    • 第三方依赖与工具
  • 开发支持与版本发布

    • 文档中心与 API 说明
    • SDK 版本与构建产物
    • 调试技巧与日志辅助

工程结构与运行环境

本文档介绍 iOS-JL_OTA 仓库的整体工程结构、目录组织方式、依赖库体系,以及运行该 SDK 与示例工程所需的环境要求,帮助开发者快速定位代码、理解模块边界并正确搭建开发环境。

Purpose and Scope

本页面覆盖以下内容:

  • 仓库顶层目录结构(code/、libs/、doc/)及各目录职责
  • 运行环境要求(iOS 版本、Xcode、硬件固件、开发语言)
  • 核心 SDK 依赖库(XCFramework)体系与职责划分
  • 示例工程中三种蓝牙连接方式的架构对比与选择指南
  • OTA 集成的核心调用流程、权限与日志配置
  • SDK 版本历史与许可证信息

以下主题属于其他页面范畴,不在本页展开:具体 OTA 升级流程的字节级分包细节、广播包解析协议字段、Hash 配对认证的密码学实现、以及完整示例 APP 的 UI 交互设计。

Overview

iOS-JL_OTA 是珠海市杰理科技股份有限公司为杰理蓝牙设备提供的 OTA 升级开发平台,基于 RCSP 协议(远程控制系统协议) 实现。该仓库同时包含三部分内容:以 XCFramework 格式发布的预编译 SDK 核心库、覆盖三种蓝牙连接方式的 iOS 示例工程源码、以及 HTML 格式的开发文档。

SDK 支持的应用场景覆盖三类典型产品:

应用类型典型产品
数传设备AC695X、AC608N、AC897、AD697N、AD698N、AC630N、AC632N
手表设备AC695X、JL701N、AC707N
音箱设备JL701N、AC897、AD697N、AD698N、700N

SDK 提供的核心能力包括:BLE 单备份/双备份 OTA 升级(含强制升级与回连机制)、Hash 配对设备认证、杰理蓝牙广播包自动解析、多种蓝牙连接方式(原生 CoreBluetooth、JL_BLEKit、JL_Assist 自定义连接),以及 v2.5.0 起新增的 GATT Over BR/EDR 经典蓝牙 OTA 升级支持。

理解工程结构的关键在于把握"业务库与连接层解耦"的设计意图:OTA 升级业务(JL_OTALib)不依赖任何特定蓝牙实现,而是通过统一的连接抽象接入三种不同的蓝牙方案,这使得开发者可以沿用已有的蓝牙管理代码,无需重写即可获得 OTA 能力。

Architecture

下图展示了仓库的整体架构与模块依赖关系:

flowchart TD
    subgraph sg_Repo["iOS-JL_OTA 仓库"]
        subgraph sg_Code["code/ 示例工程"]
            MiniDemo["MiniDemo 迷你示例"]
            JLOTA["JL_OTA 完整示例"]
            MiniSingle["MiniSingleDemo<br/>原生 CoreBluetooth"]
            JLBleKitDemo["JLBleKitOTADemo<br/>JL_BLEKit 连接"]
            JLAssistDemo["JLAssistOTADemo<br/>JL_Assist 连接"]
            BleManager["BleManager"]
            BleByAssist["BleByAssist"]
            SDKBleManager["SDKBleManager"]
            Views["Views UI 视图"]
        end
        subgraph sg_Libs["libs/ 核心 SDK (XCFramework)"]
            OTALib["JL_OTALib<br/>OTA 升级业务库"]
            AdvParse["JL_AdvParse<br/>广播包解析库"]
            HashPair["JL_HashPair<br/>设备认证库"]
            BLEKit["JL_BLEKit<br/>蓝牙连接核心库(可选)"]
            LogHelper["JLLogHelper<br/>日志辅助库"]
        end
        subgraph sg_Doc["doc/ 文档资源"]
            ReleaseDoc["Release_V2.5.0 文档"]
        end
    end

    MiniDemo --> MiniSingle
    MiniDemo --> JLBleKitDemo
    MiniDemo --> JLAssistDemo
    JLOTA --> BleManager
    JLOTA --> BleByAssist
    JLOTA --> SDKBleManager
    JLOTA --> Views

    MiniSingle --> OTALib
    JLBleKitDemo --> OTALib
    JLAssistDemo --> OTALib
    BleManager --> OTALib
    BleByAssist --> OTALib
    SDKBleManager --> OTALib

    OTALib --> AdvParse
    OTALib --> HashPair
    OTALib --> LogHelper
    OTALib -.-> BLEKit
    JLBleKitDemo --> BLEKit
    SDKBleManager --> BLEKit

架构分层说明:

  • libs/(核心 SDK 层):所有能力以 XCFramework 形式提供。JL_OTALib 是唯一的 OTA 业务入口,内部依赖 JL_AdvParse(广播解析)与 JL_HashPair(Hash 认证);JLLogHelper 自 v2.3.1 起被分离为独立日志模块,被各库共用;JL_BLEKit 是可选蓝牙连接核心库,仅在开发者选择"SDK 蓝牙连接"方式时导入。
  • code/(示例应用层):分为迷你示例(每种连接方式一个独立工程)与完整示例(一个工程内同时包含三种蓝牙管理实现,通过 BleManager、BleByAssist、SDKBleManager 三个模块分别对应原生、Assist、BLEKit 连接)。所有示例都只面向 JL_OTALib 编程,连接层差异被隔离在各自的 Manager 中。
  • doc/(文档层):存放随版本发布的 HTML 开发文档,Release_V2.5.0 为当前最新版本。

这样的分层设计意图在于:业务(OTA)与传输(BLE)彻底解耦。OTA 升级逻辑不关心数据是通过 CoreBluetooth、杰理蓝牙库还是外部蓝牙桥接发送的,只要连接层遵循统一的命令/回调契约即可工作;同时将广播解析、设备认证、日志三个横切关注点独立成库,使各库可以独立演进与复用。

工程结构详解

仓库的目录树定义如下(摘自 README 的工程结构章节):

iOS-JL_OTA/
├── code/                           # 示例程序源码
│   ├── MiniDemo/                   # 迷你示例工程
│   │   ├── MiniSingleDemo/         #   原生 CoreBluetooth 连接示例
│   │   ├── JLBleKitOTADemo/        #   JL_BLEKit 连接示例
│   │   └── JLAssistOTADemo/        #   JL_Assist 自定义连接示例
│   └── JL_OTA/                     # 完整 OTA 应用示例
│       ├── 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/                            # 文档资源
    └── Release_V2.5.0/             #   最新版本文档

Source: README.md

关键目录职责

目录作用
code/MiniDemo/迷你示例:三种连接方式各自独立的示例工程,适合对照学习单一连接方案
code/JL_OTA/完整示例:包含完整 UI 与蓝牙管理的 OTA 应用,三个 Manager 模块并存的参考工程
libs/核心 SDK:XCFramework 格式的预编译 OTA 升级库,使用 Embed & Sign 方式集成
doc/开发文档:随版本发布的 HTML 文档与 API 说明

示例工程内部模块

code/JL_OTA/ 完整示例的四个子模块体现了连接抽象的设计:

  • BleManager/:基于原生 CoreBluetooth 的自定义连接实现,开发者完全掌控 BLE 扫描、连接、服务发现与分包发送;
  • BleByAssist/:JL_Assist 自定义连接实现,适用于已有外部蓝牙管控、或需要将 OTA 桥接到既有蓝牙层的场景;
  • SDKBleManager/:基于 JL_BLEKit 的连接实现,由 SDK 封装蓝牙细节,集成成本最低;
  • Views/:与蓝牙无关的纯 UI 层,通过统一的 Manager 接口与底层交互。

这一划分说明完整示例把"连接策略"作为可替换组件:切换连接方式时只需替换 Manager 实现,Views/ 与 OTA 业务代码无需改动。

运行环境要求

SDK 及示例工程的运行环境要求如下:

类别要求说明
iOS 系统iOS 12.0+最低支持版本,BLE 功能依赖
Xcode 版本14.0+建议使用最新版本
硬件要求支持 RCSP 协议的固件AC695X、AC697X、AC695X 等 SDK
语言支持Objective-C / Swift提供完整的 API 支持
许可证Apache 2.0开源协议,版权归珠海市杰理科技股份有限公司

Source: README.md

选择 Xcode 14.0+ 的原因在于 XCFramework 的构建与签名机制依赖较新的 Xcode 工具链;iOS 12.0+ 的下限则覆盖了绝大多数支持 BLE 的存量设备,同时保证 Swift/ObjC 混编 API 的可用性。

克隆与集成

git clone https://github.com/Jieli-Tech/iOS-JL_OTA.git
cd iOS-JL_OTA

Source: README.md

集成 SDK 的标准步骤为:

  1. 导入框架:将 libs/ 目录下的 XCFramework 添加到项目中,并设置 Embed & Sign;
  2. 配置权限:在 Info.plist 中添加蓝牙使用权限描述;
  3. 初始化 SDK:参考示例工程的初始化代码进行集成;
  4. 开始开发:使用 SDK 提供的 API 进行 OTA 升级功能开发。

依赖库体系

libs/ 下的五个 XCFramework 构成了完整的 SDK 依赖体系,按"必须/可选"分类如下。

必须导入的库

库名说明
JL_OTALib.xcframeworkOTA 升级业务库,核心 API 入口
JL_AdvParse.xcframework杰理蓝牙设备广播包解析库
JL_HashPair.xcframework设备认证业务库(Hash 配对)
JLLogHelper.xcframework日志打印收集库

可选导入的库

库名说明
JL_BLEKit.xcframework蓝牙连接核心库,仅在需要使用杰理集成的蓝牙库时导入

Source: README.md

为什么广播解析与认证是"必须"的? 因为 OTA 升级流程强依赖这两个环节:JL_AdvParse 负责在扫描阶段识别杰理设备广播并提取连接参数,JL_HashPair 负责建立安全连接前的设备认证。二者从 v2.1.0 开始从 OTA 主库中分离为独立库,使各自的版本可以独立迭代;JL_BLEKit 保持可选,是因为 SDK 刻意支持"完全自研蓝牙层"的接入方式,避免强制引入蓝牙实现。

三种蓝牙连接方式

SDK 支持三种蓝牙连接方式,各自对应独立的示例工程。选择哪种方式取决于开发者对蓝牙层的掌控需求:

连接方式适用场景Demo 路径
原生 CoreBluetooth完全掌控 BLE 扫描、连接、服务与分包发送code/MiniDemo/MiniSingleDemo/
JL_BLEKit快速集成、减少蓝牙细节处理code/MiniDemo/JLBleKitOTADemo/
JL_Assist 自定义已有外部蓝牙管控或需桥接到既有蓝牙层code/MiniDemo/JLAssistOTADemo/

Source: README.md

flowchart TD
    Start([需要集成 OTA 的 iOS 工程]) --> Q{"现有蓝牙能力?"}
    Q -->|"无,希望完全自研"| Native["原生 CoreBluetooth<br/>MiniSingleDemo"]
    Q -->|"无,希望快速集成"| BLEKit["JL_BLEKit 连接<br/>JLBleKitOTADemo"]
    Q -->|"已有蓝牙管控层"| Assist["JL_Assist 自定义<br/>JLAssistOTADemo"]
    Native --> OTA["JL_OTALib OTA 业务"]
    BLEKit --> OTA
    Assist --> OTA

选择指南(摘自 README):

  • 完全掌控 BLE 扫描、连接、服务与分包发送 → 选择原生自定义连接
  • 快速集成、减少蓝牙细节处理 → 选择 SDK 蓝牙连接(JL_BLEKit)
  • 已有外部蓝牙管控或需桥接到既有蓝牙层 → 选择 JL_Assist 自定义连接

Source: README.md

无论选择哪种连接方式,上层 OTA 业务都统一走 JL_OTALib,这正是"业务与传输解耦"架构的直接体现。

核心调用流程

OTA 升级的完整调用时序如下(README 定义的标准集成流程):

sequenceDiagram
    participant APP as iOS App
    participant BLE as 蓝牙连接层
    participant OTA as JL_OTALib
    participant DEV as 杰理设备

    APP->>BLE: 设备连接 + 订阅
    BLE-->>OTA: noteEntityConnected
    OTA-->>APP: 连接状态回调
    APP->>OTA: cmdTargetFeature(查询设备能力)
    OTA-->>APP: 能力信息返回
    APP->>OTA: cmdOTAData(data) 发送升级数据
    OTA->>DEV: 分包写入 OTA 数据
    DEV-->>OTA: 数据确认
    OTA-->>APP: 委托回调 otaUpgradeResult / otaDataSend
    Note over APP,DEV: 升级进行中,持续分包交互
    BLE-->>OTA: noteEntityDisconnected(断开)
    OTA-->>APP: 回连/结束处理

Source: README.md

流程要点

  1. 连接与订阅:App 建立 BLE 连接并订阅设备通知,蓝牙层上报 noteEntityConnected;
  2. 能力查询:App 调用 cmdTargetFeature 查询设备支持的 OTA 能力(单备份/双备份、空间等),为后续升级策略提供依据;
  3. 数据下发:App 调用 cmdOTAData(data) 将升级文件分包发送给设备;
  4. 进度回调:升级过程通过委托回调 otaUpgradeResult(升级结果)与 otaDataSend(数据发送进度)反馈给 App;
  5. 断开处理:连接断开时蓝牙层上报 noteEntityDisconnected,App 据此执行回连或结束流程(v2.5.0 修复了 OTA 回连超时问题)。

该流程体现了 SDK 的事件驱动模型:App 不主动轮询设备状态,而是由蓝牙层与 OTA 库通过回调反向通知,从而避免阻塞主线程并简化状态管理。

配置说明

权限配置

在 Info.plist 中添加以下蓝牙权限:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>需要使用蓝牙功能连接杰理设备</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>需要作为蓝牙外设连接杰理设备</string>

Source: README.md

NSBluetoothAlwaysUsageDescription 是 iOS 13+ 持续使用蓝牙所必需的权限描述;NSBluetoothPeripheralUsageDescription 用于兼容低版本 iOS 的外设角色声明。两者缺一不可,否则系统会在首次扫描/连接时直接终止 App。

日志管理

JLLogHelper 默认开启日志打印与存储,可通过以下接口控制:

// Objective-C
[JLLogManager clearLog]; // 清空日志
[JLLogManager setLog:false IsMore:false Level:JLLOG_COMPLETE]; // 关闭日志打印
[JLLogManager saveLogAsFile:false]; // 关闭日志存储
[JLLogManager logWithTimestamp:false]; // 关闭日志打印时间

Source: README.md

// Swift
JLLogManager.saveLog(asFile: true)
JLLogManager.setLog(true, isMore: false, level: .COMPLETE)
JLLogManager.log(withTimestamp: true)
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/abc.txt"
JLLogManager.redirectLogPath(path) // 重置保存路径
JLLogManager.clearLog()
JLLogManager.collectLog { str in
    print(str) // 回调所有的日志打印内容
}
JLLogManager.logSomething("abcd")

Source: README.md

日志库自 v2.3.1 起作为独立运行模块提供,支持打印开关、详细级别(JLLOG_COMPLETE)、文件存储开关、时间戳、路径重定向、日志收集回调等能力。在定位 OTA 失败问题时,可开启 collectLog 将 SDK 内部日志实时回调给 App 侧展示,或开启 saveLogAsFile 导出日志文件用于远程排查。

API 参考(核心接口一览)

以下接口为 OTA 集成过程中最常使用的 SDK 入口(来自 README 定义的集成契约,完整签名以 doc/Release_V2.5.0/ 文档为准)。

连接与状态回调

回调/方法时机说明
noteEntityConnected设备连接成功蓝牙层通知 OTA 库设备已就绪
noteEntityDisconnected设备断开触发回连或结束流程
cmdTargetFeature连接后、升级前查询设备 OTA 能力(备份方式、可用空间等)
cmdOTAData(data)能力确认后将升级数据分包下发到设备
otaUpgradeResult升级结束委托回调,返回升级结果
otaDataSend升级过程中委托回调,反馈数据发送进度

JLLogManager 日志接口

方法作用
setLog(_:isMore:level:)开关日志打印并设置详细级别(如 JLLOG_COMPLETE)
saveLog(asFile:) / saveLogAsFile:开关日志落盘存储
redirectLogPath(_:)重置日志文件保存路径
clearLog()清空日志
collectLog { str in }回调所有日志内容(实时收集)
log(withTimestamp:) / logWithTimestamp:开关日志时间戳
logSomething(_:)手动写入自定义日志

Source: README.md

版本历史与演进

SDK 版本的演进脉络反映了工程结构的变化:

版本发布日期主要更新
v2.5.02026/02/04增加 GATT Over BR/EDR 设备 OTA 升级支持;修复 OTA 回连超时问题
v2.4.02025/10/13OTA 超时处理逻辑优化;增加重复序列号容错;增加特殊空间复用升级支持;增加单备份 SDK 内部自动回连接口
v2.3.12024/12/12分离日志打印库为独立运行模块;增加所有命令的超时检测;增加 OTA 升级的错误回调;增加 OTA 对象管理容错
v2.1.02023/03/28性能优化;分离 OTA 模块、设备认证配对业务、广播包解析模块为独立库
v2.0.02021/10/14支持 BLE 单备份/双备份升级;支持浏览器与第三方电脑软件导入升级文件;可选 BLE 广播包过滤与握手连接

Source: README.md

结构演进的关键节点: v2.1.0 将 OTA 主库拆分为"OTA 业务 + 认证 + 广播解析"三个独立库,奠定了当前 libs/ 目录的模块形态;v2.3.1 又将日志模块独立为 JLLogHelper,并引入全命令超时检测与错误回调;v2.5.0 扩展了传输层能力(GATT Over BR/EDR),使同一套 OTA 业务同时覆盖 BLE 与经典蓝牙。

对应地,示例 APP 版本(v3.5.2 起使用 SDK v2.5.0)与 SDK 版本同步演进,其中 v3.3.0 完成 UI 重构并新增自动化测试与广播音箱模块。

失败模式与边界情况

从版本历史与集成说明可以梳理出 SDK 已处理的典型失败场景:

  • 回连超时:升级过程中蓝牙意外断开时,SDK 依据设备地址自动回连。v2.5.0 修复了回连超时导致升级中断的问题;v2.4.0 起单备份升级支持 SDK 内部自动回连接口,App 无需自行实现重连逻辑。
  • 命令超时:v2.3.1 起所有命令具备超时检测,避免设备无响应时流程永久挂起;v2.4.0 进一步优化超时处理逻辑,缩短异常路径的恢复时间。
  • 重复序列号:v2.4.0 增加对重复序列号的容错处理,防止数据包重发或乱序导致的分包计数错乱。
  • 对象管理容错:v2.3.1 增加 OTA 对象管理容错,防止多次初始化的重复创建导致资源泄漏。
  • 错误回调缺失:早期版本升级失败只能依赖超时间接判断;v2.3.1 起增加 OTA 升级错误回调(otaUpgradeResult 携带错误信息),App 可以及时向用户反馈失败原因。

边界条件提示: 设备空间不足(需通过 cmdTargetFeature 查询)、固件不兼容(固件需支持 RCSP 协议)、以及强制升级场景下设备未处于可升级状态,均属于需要 App 层结合设备能力信息进行前置校验的场景。

性能与运维考虑

  • 分包发送效率:cmdOTAData(data) 采用分包发送,数据量较大时发送节奏由 SDK 内部调度;App 应避免在回调线程中执行耗时操作,防止阻塞数据下发。
  • 日志开销:JLLogHelper 默认开启打印与存储,生产环境建议通过 setLog:false 与 saveLogAsFile:false 关闭以降低 I/O 开销;排查问题时再开启 collectLog 实时收集。
  • 线程模型:回调(noteEntityConnected、otaUpgradeResult 等)由蓝牙层线程触发,App 侧 UI 更新需自行切换到主线程。
  • 调试手段:使用 Xcode Console 查看实时日志;SDK 侧问题可参考在线文档中心的调试说明,杰理 OTA APP 还支持导出打印日志用于远程分析。

扩展点

SDK 通过以下方式提供扩展能力:

  1. 连接层替换:JL_Assist 自定义连接允许将 OTA 桥接到任意既有蓝牙层,是最大的扩展点——第三方蓝牙栈、外部连接管理模块均可接入;
  2. 可选库裁剪:不使用 JL_BLEKit 时可不导入,减小包体积;
  3. 升级文件导入渠道:支持浏览器传输与第三方电脑软件导入 OTA 升级文件,App 可在此基础上扩展更多文件来源;
  4. 日志集成:JLLogManager.collectLog 可将 SDK 日志接入 App 自身的日志体系(如 Crashlytics、自建日志平台)。

Related Links

  • README.md(中文总览)
  • README_EN.md(英文总览)
  • LICENSE(Apache 2.0)
  • 杰理在线文档中心:https://doc.zh-jieli.com/Apps/iOS/ota/zh-cn/master/index.html
  • 问题反馈:https://github.com/Jieli-Tech/iOS-JL_OTA/issues
Prev
项目概述与功能特性