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

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

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

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

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

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

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

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

原生 CoreBluetooth 连接

本页介绍 JL OTA SDK 的"自定义蓝牙连接"方式:宿主 App 直接使用 Apple CoreBluetooth 框架(CBCentralManager / CBPeripheral)完成扫描、连接、发现服务与特征、订阅通知与数据收发,并将这条原生 BLE 通道桥接给 JL_OTAManager 与 JLHashHandler 来执行设备认证与 OTA 升级。

Purpose and Scope

本页覆盖以下内容:

  • 原生连接管理器 BleManager(CBCentralManagerDelegate / CBPeripheralDelegate)的职责:扫描、连接、断开、MTU 分片写入、重连与超时控制。
  • 与 OTA SDK 的衔接点:连接就绪后初始化 OTA 上下文(mBLE_UUID / mBLE_NAME)、noteEntityConnected()、cmdTargetFeature()、cmdOTAData()、cmdOtaDataReceive()。
  • 认证数据与 OTA 数据的分流逻辑(JLHashHandler.inputPairData vs cmdOtaDataReceive)。
  • 升级失败场景下的重连与重试策略(UUID / MAC 重连、命令超时重试)。

以下主题属于兄弟页面,不在本页展开:

  • SDK 内置蓝牙管理(JL_BLEKit.xcframework 的 BleManager / JL_EntityM),请参见 bluetooth-connectivity.sdk-blekit。
  • GATT Over EDR(经典蓝牙通道承载 GATT),请参见 bluetooth-connectivity.gatt-over-edr。
  • OTA 协议命令(Opcode 0xe2–0xe8)与 JL_OTAResult 枚举语义,请参见 ota-protocol。

Overview

JL OTA SDK 提供两种蓝牙接入方式:

  1. SDK 内置蓝牙管理:使用 JL_BLEKit.xcframework,由 SDK 内部封装扫描、连接与数据收发,App 只需调用 JL_EntityM / BleManager 的高层接口。
  2. 自定义蓝牙连接(本页主题):App 自己持有 CBCentralManager 并实现 CBCentralManagerDelegate / CBPeripheralDelegate,把 CBPeripheral 与特征通道交给 JL_OTAManager 使用。SDK 只负责 OTA 业务逻辑与数据解析,不感知蓝牙链路细节。

选择自定义连接方式的典型场景:App 已有成熟的蓝牙连接层、需要同时管理多台设备、或需要与既有配对/认证逻辑共存。此模式下 SDK 侧只要求三件事:告知设备标识(mBLE_UUID / mBLE_NAME)、通知连接状态(noteEntityConnected / noteEntityDisconnected)、提供数据收发回调(otaDataSend 写设备、cmdOtaDataReceive 收设备数据)。

Architecture

flowchart TD
    subgraph sg_App["App 层(自定义蓝牙)"]
        VC["ViewController"]
        OTA["OTAActionManager"]
        BM["BleManager<br/>CBCentralManagerDelegate<br/>CBPeripheralDelegate"]
    end

    subgraph sg_CB["CoreBluetooth 原生栈"]
        CM["CBCentralManager"]
        PERI["CBPeripheral"]
    end

    subgraph sg_SDK["JL OTA SDK"]
        OM["JL_OTAManager"]
        HH["JLHashHandler"]
        LIB["JL_OTALib"]
    end

    subgraph sg_Dev["杰理设备"]
        DEV["耳机 / 音箱<br/>(GATT Server)"]
    end

    VC -->|"选择设备"| BM
    BM -->|"scan / connect / write"| CM
    CM -->|"发现与连接"| PERI
    PERI -->|"服务发现 / 通知 / 读写"| DEV

    OM -->|"otaDataSend 数据下发"| BM
    BM -->|"cmdOtaDataReceive / inputPairData 数据上送"| OM
    OM -->|"认证数据"| HH
    HH -->|"hashOnPairOutputData 写回设备"| BM
    OM -->|"OTA 流程控制"| LIB

架构要点:

  • BleManager 是原生桥:它是 App 与 CoreBluetooth 之间的唯一入口,同时承担连接生命周期管理与数据通道职责,是 SDK 回连、数据写入的落点。
  • JL_OTAManager 只面向业务:它不直接持有 CBPeripheral,而是通过 delegate 回调(otaDataSend)向 BleManager 请求写数据,通过 cmdOtaDataReceive 接收设备上行数据,实现"蓝牙无关"的 OTA 引擎。
  • 认证与升级共用同一条原生通道:连接建立后,JLHashHandler 先完成配对认证(bluetoothPairingKey),认证通过后再由 JL_OTAManager 执行特性查询与 OTA,两条数据流在 BleManager 处汇合。

Core Flow

sequenceDiagram
    participant VC as ViewController
    participant BM as BleManager
    participant CB as CoreBluetooth
    participant OM as JL_OTAManager
    participant HH as JLHashHandler
    participant DEV as 杰理设备

    VC->>BM: startScan()
    BM->>CB: scanForPeripherals(withServices: nil)
    CB-->>BM: didDiscover(peripheral, advertisementData, rssi)
    VC->>BM: connect(peripheral:)
    BM->>CB: connect(peripheral, options: nil)
    CB-->>BM: didConnect(peripheral)
    BM->>CB: discoverServices(nil)
    CB-->>BM: didDiscoverServices
    BM->>CB: discoverCharacteristics(for: service)
    CB-->>BM: didDiscoverCharacteristicsFor
    BM->>CB: setNotifyValue(true, for: characteristicWrite)
    CB-->>BM: didUpdateNotificationStateFor
    BM-->>OM: onPeripheralReady → mBLE_UUID / mBLE_NAME

    OM->>OM: noteEntityConnected()
    OM->>OM: cmdTargetFeature()
    OM-->>HH: 认证触发(hashResetPair / bluetoothPairingKey)
    HH-->>BM: hashOnPairOutputData(data)
    BM->>DEV: writeValue(data, for: characteristic, .withoutResponse)
    DEV-->>BM: didUpdateValueFor(characteristic)
    BM-->>HH: inputPairData(data)(认证前)

    OM-->>BM: otaDataSend(data)
    BM->>DEV: writeValue(按 MTU 分片)
    DEV-->>BM: didUpdateValueFor(characteristic)
    BM-->>OM: cmdOtaDataReceive(data)(认证后)

流程说明:

  1. BleManager.startScan() 以 withServices: nil 全量扫描,扫描结果在 didDiscover 中回调。
  2. 用户选中设备后 connect(peripheral:),成功后 SDK 需要先拿到设备标识(UUID 与名称),再调用 noteEntityConnected() 通知 OTA 引擎"上下文就绪"。
  3. 连接建立后,原生栈完成服务发现、特征发现与通知订阅;didUpdateNotificationStateFor 代表数据通道打通,此时才初始化 OTA 上下文(onPeripheralReady)。
  4. 认证阶段,JLHashHandler 产出的配对数据经 hashOnPairOutputData 写入设备,设备响应进入 inputPairData。
  5. 认证完成后进入 OTA 阶段:JL_OTAManager 通过 otaDataSend 把待发送数据交给 BleManager 分片写入,设备回包统一经 cmdOtaDataReceive 交还 SDK 解析,驱动升级进度。

原生连接管理器(BleManager)

BleManager(单例 BleManager.shared)是自定义连接方式的核心,封装了全部 CoreBluetooth 原生调用。其公开行为可从开发示例文档的源码摘录中还原:

扫描与停止扫描

// 扫描与停止扫描
func startScan() {
    centralManager.scanForPeripherals(withServices: nil, options: nil)
}

func stopScan() {
    centralManager.stopScan()
}

Source: OTA 升级开发示例.md

设计意图:withServices: nil 表示不过滤服务 UUID,全量扫描。这是因为杰理设备的广播可能不包含目标 Service UUID,或 App 需要按广播包中的自定义字段(如厂商数据中的 MAC 地址)来筛选设备;过滤逻辑放在 didDiscover 回调中自行实现更灵活。

连接与断开

// 连接与断开
func connect(peripheral: CBPeripheral) {
    centralManager.connect(peripheral, options: nil)
}

func disconnect(peripheral: CBPeripheral) {
    centralManager.cancelPeripheralConnection(peripheral)
}

Source: OTA 升级开发示例.md

连接选项传 nil,表示不请求重连(CBConnectPeripheralOptionNotifyOnConnectionKey 等均为默认值)。断开统一走 cancelPeripheralConnection,SDK 侧会通过 JL_OTAResultDisconnect 感知并停止升级流程。

MTU 分片写入

// 数据写入(按设备 MTU 分片)
func write(data: Data) {
    guard let characteristic = characteristicWrite, let peripheral = currentPeripheral else { return }
    let mtu = peripheral.maximumWriteValueLength(for: .withoutResponse)
    var len = 0
    while len < data.count {
        let end = min(len + mtu, data.count)
        peripheral.writeValue(data.subdata(in: len ..< end), for: characteristic, type: .withoutResponse)
        len = end
    }
}

Source: OTA 升级开发示例.md

这是整个数据通道中最关键的实现:

  • 写入类型固定为 .withoutResponse(无响应写),避免每包等待 ATT 应答,吞吐更高,适合 OTA 这种大数据量场景;
  • 每次写入前通过 maximumWriteValueLength(for:) 查询当前连接协商出的 MTU(iOS 协商后通常为 185/247 字节),把一整帧 OTA 数据切成 MTU 大小的分片依次下发;
  • characteristicWrite 是 App 在 didDiscoverCharacteristicsFor 中保存的写特征(杰理协议中为 RCSP 写通道),currentPeripheral 为当前连接的外设。

重连与超时控制

// 通过 UUID 重连设备并启动超时计时
func reConnectWithUUID(uuid: String) {
    reconnectUUID = uuid
    reconnectMac = nil
    JLLogManager.logLevel(.DEBUG, content: "reConnectWithUUID: \(uuid)")
    startScan()
    startTimeout()
}

// 通过 MAC 地址重连设备并启动超时计时
func reConnectWithMac(mac: String) {
    reconnectUUID = nil
    reconnectMac = mac
    JLLogManager.logLevel(.DEBUG, content: "reConnectWithMac: \(mac)")
    startScan()
    startTimeout()
}

Source: OTA 升级开发示例.md

设计意图:BLE 地址(reconnectMac)与系统分配的 UUID(reconnectUUID)是两套标识——iOS 对同一外设的 UUID 在系统层面基本稳定,但用户若"忽略此设备"或系统重置后会变化;MAC 地址则来自广播包中杰理厂商数据字段(kCBAdvDataManufacturerData),可跨系统稳定标识设备。两种重连入口对应 SDK 的 JL_OTAResultReconnect(UUID)与 JL_OTAResultReconnectWithMacAddr(MAC)两种回连诉求,startTimeout() 防止扫描阶段无限期挂起。

连接生命周期与 SDK 桥接

连接就绪的判定在 didUpdateNotificationStateFor 之后:只有通知订阅成功,设备上行数据才能到达,因此 OTA 上下文初始化(onPeripheralReady)必须发生在此之后。

// 3) 设备连接完成后初始化 OTA 上下文(接口规范)
private func onPeripheralReady(_ peripheral: CBPeripheral) {
    otaManager.mBLE_UUID = peripheral.identifier.uuidString
    otaManager.mBLE_NAME = peripheral.name ?? ""

    otaManager.noteEntityConnected() // /doc/API 说明.md → 3.4.1 设备操作
    otaManager.cmdTargetFeature()    // /doc/API 说明.md → 3.3.3 状态查询
}

Source: OTA 升级开发示例.md

要点:

  • mBLE_UUID / mBLE_NAME 是 SDK 识别设备、执行重连与日志排查的依据,必须在任何 OTA 命令前赋值;
  • noteEntityConnected() 通知 SDK 设备已连接,内部会复位命令序号(SN)等状态;
  • cmdTargetFeature() 查询设备特性(是否支持 OTA、TWS、EDR 等),其结果通过 otaFeatureResult 委托回调返回。

数据上行回调按认证状态分流(最小示例):

// 数据通道:认证数据与 OTA 数据分流
BleManager.shared.subNotifySubject
    .subscribe(onNext: { [weak self] data in
        guard let self = self else { return }
        if !self.isAuthed {
            self.auth.inputPairData(data)
            return
        }
        self.otaManager.cmdOtaDataReceive(data)
    })
    .disposed(by: disposeBag)

Source: OTA 升级开发示例.md

设计意图:认证完成前后,同一根特征通知通道上的报文属于不同协议域。认证前的报文是 BLE 配对握手数据(交给 JLHashHandler.inputPairData),认证后的报文才是 RCSP/OTA 响应(交给 cmdOtaDataReceive)。用一个布尔状态(isAuthed)在入口处分流,避免认证报文被误解析为 OTA 命令导致协议错乱。

异常与重试策略

升级过程中断是 BLE 场景的高频故障,示例文档给出了三种典型处置(Objective-C 实现):

- (void)otaUpgradeResult:(JL_OTAResult)result Progress:(float)progress {
    switch (result) {
        case JL_OTAResultReconnect: {
            NSString *uuid = self.otaManager.mBLE_UUID;
            [[BleManager shared] reConnectWithUUID:uuid];
            break;
        }
        case JL_OTAResultReconnectWithMacAddr: {
            NSString *mac = self.otaManager.bleAddr;
            [[BleManager shared] reConnectWithMac:mac];
            break;
        }
        case JL_OTAResultFailCmdTimeout: {
            if (self.retryCount < 3) {
                self.retryCount += 1;
                NSTimeInterval delay = (NSTimeInterval)self.retryCount;
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    [self.otaManager cmdTargetFeature];
                });
            }
            break;
        }
        case JL_OTAResultLowPower:
        case JL_OTAResultDisconnect:
        default:
            break;
    }
}

Source: OTA 升级开发示例.md

策略解读:

  • JL_OTAResultReconnect:SDK 期望按 UUID 回连(常见于升级第一阶段设备重启后广播变化,但系统 UUID 未变);
  • JL_OTAResultReconnectWithMacAddr:SDK 期望按 MAC 回连(常见于设备重启后广播名/UUID 变化,只能靠广播包厂商数据中的 MAC 定位);
  • JL_OTAResultFailCmdTimeout:命令超时,采用"最多重试 3 次、延时按次数递增(1s/2s/3s)"的退避策略重新查询特性,避免高频重试加剧链路拥塞;
  • JL_OTAResultLowPower / JL_OTAResultDisconnect:低电与断连属不可恢复或需人工介入的场景,示例中直接放弃重试。

数据模型与关键状态

原生连接层不需要持久化存储,但存在一组运行时状态,驱动重连与写入逻辑:

状态字段用途来源
currentPeripheral当前连接的 CBPeripheral,写入目标didConnect 时保存
characteristicWrite已发现的写特征(RCSP 写通道)didDiscoverCharacteristicsFor 时保存
reconnectUUID待重连设备的系统 UUIDreConnectWithUUID(uuid:) 设置
reconnectMac待重连设备的 MAC 地址reConnectWithMac(mac:) 设置
isAuthed认证状态,决定上行数据分流方向认证回调 bluetoothPairingKey 置位
subNotifyInitSubject通知订阅完成事件(RxSwift)didUpdateNotificationStateFor 触发
subNotifySubject设备上行数据流(RxSwift)didUpdateValueFor 触发

这些状态只存活于内存中;跨启动恢复设备连接依赖系统蓝牙持久化(CoreBluetooth 会按 CBPeripheral.identifier 保留已知外设)。

使用示例

基础示例:完整 OTA 调用链(Swift)

import UIKit
import CoreBluetooth
import JL_OTALib

/// OTA 示例控制器:演示 JL_OTAManager 标准调用流程
final class OTAExampleViewController: UIViewController, JL_OTAManagerDelegate {

    private let otaManager = JL_OTAManager.getOTAManager() // 接口文档:getOTAManager

    override func viewDidLoad() {
        super.viewDidLoad()
        // 1) 绑定 delegate(接口规范)
        otaManager.delegate = self // /doc/API 说明.md → 3.5 回调协议

        // 2) 扫描并连接设备
        BleManager.shared.startScan()
        // 选择设备后:BleManager.shared.connect(peripheral: sel)
    }

    // 3) 设备连接完成后初始化 OTA 上下文(接口规范)
    private func onPeripheralReady(_ peripheral: CBPeripheral) {
        otaManager.mBLE_UUID = peripheral.identifier.uuidString
        otaManager.mBLE_NAME = peripheral.name ?? ""

        otaManager.noteEntityConnected() // /doc/API 说明.md → 3.4.1 设备操作
        otaManager.cmdTargetFeature()    // /doc/API 说明.md → 3.3.3 状态查询
    }

    // 4) 发起 OTA 升级(委托驱动进度,接口文档:cmdOTAData)
    private func startUpgrade(with data: Data) {
        otaManager.cmdOTAData(data) // /doc/API 说明.md → 3.4.2 OTA 操作
    }

    // 5) 取消升级(接口文档:cmdOTACancelResult)
    private func cancelUpgrade() {
        otaManager.cmdOTACancelResult { result in
            print("OTA 取消:\(result)")
        }
        otaManager.noteEntityDisconnected() // /doc/API 说明.md → 3.4.1 设备操作
    }

    // 6) 委托回调(接口文档:JL_OTAManagerDelegate)
    func otaUpgradeResult(_ result: JL_OTAResult, progress: Float) {
        print("升级状态:\(result) 进度:\(progress)") // /doc/API 说明.md → 3.5 回调协议
    }
    func otaDataSend(_ data: Data) {
        BleManager.shared.write(data: data)
    }
    func otaCancel() {}
    func otaFeatureResult(_ manager: JL_OTAManager) {}
}

Source: OTA 升级开发示例.md

高级示例:订阅完成后自动认证 + 查询特性

import RxSwift
import JL_OTALib
import JL_HashPair
import CoreBluetooth

/// 订阅完成后自动执行设备认证并查询特性的最小示例
final class OTAAutoAuthMini: JLHashHandlerDelegate {
    private let otaManager = JL_OTAManager.getOTAManager()
    private let auth = JLHashHandler()
    private let disposeBag = DisposeBag()
    private var isAuthed = false

    init() {
        auth.delegate = self

        // 订阅完成:设置设备标识并触发认证与特性查询
        BleManager.shared.subNotifyInitSubject
            .subscribe(onNext: { [weak self] peripheral in
                guard let self = self else { return }
                self.otaManager.mBLE_UUID = peripheral.identifier.uuidString
                self.otaManager.mBLE_NAME = peripheral.name ?? ""
                self.otaManager.noteEntityConnected()
                self.auth.hashResetPair()
                self.auth.bluetoothPairingKey(nil) { status in
                    if status {
                        self.isAuthed = true
                        self.otaManager.cmdTargetFeature()
                    }
                }
            })
            .disposed(by: disposeBag)

        // 数据通道:认证数据与 OTA 数据分流
        BleManager.shared.subNotifySubject
            .subscribe(onNext: { [weak self] data in
                guard let self = self else { return }
                if !self.isAuthed {
                    self.auth.inputPairData(data)
                    return
                }
                self.otaManager.cmdOtaDataReceive(data)
            })
            .disposed(by: disposeBag)
    }

    // 认证输出:写入设备
    func hash(onPairOutputData data: Data) {
        BleManager.shared.write(data: data)
    }
}

Source: OTA 升级开发示例.md

配置选项

选项类型默认值说明
scanForPeripherals(withServices:)[CBUUID]?nil(全量扫描)扫描过滤;示例不传服务 UUID,靠 didDiscover 回调自行筛选
connect(peripheral:options:)[String: Any]?nil连接选项;示例未启用系统级重连提示
写入类型CBCharacteristicWriteType.withoutResponseOTA 数据全部使用无响应写以提升吞吐
分片大小Int(由系统返回)peripheral.maximumWriteValueLength(for: .withoutResponse)随连接协商 MTU 动态变化,每次写入前查询
重连方式String?二选一(UUID / MAC)reConnectWithUUID 或 reConnectWithMac,由 JL_OTAResult 决定
命令超时重试Int最多 3 次,延时 1s/2s/3s 递增应对 JL_OTAResultFailCmdTimeout
日志等级JLLogManager.logLevel.DEBUG重连入口打印 UUID/MAC,便于联调定位

上述默认值均取自 OTA 升级开发示例.md 的源码摘录;实际工程中这些参数可随业务需要调整。

API Reference(原生连接层)

以下方法为 BleManager 暴露给上层与 SDK 的关键接口(签名依据示例源码摘录整理):

startScan()

启动 CoreBluetooth 全量扫描。扫描回调 centralManager(_:didDiscover:advertisementData:rssi:) 中可结合 peripheral.name、广播包厂商数据(MAC)与目标 UUID 做重连匹配。

stopScan()

停止扫描。进入连接阶段或重连成功后应调用,以节省功耗。

connect(peripheral: CBPeripheral)

发起连接。参数: peripheral — 待连接外设(来自扫描结果)。连接结果在 centralManager(_:didConnect:) 回调。

disconnect(peripheral: CBPeripheral)

调用 cancelPeripheralConnection 断开。SDK 侧表现为 JL_OTAResultDisconnect。

write(data: Data)

把一帧数据按当前 MTU 分片后写入写特征。 参数: data — 完整帧(认证数据或 OTA 数据)。 前置条件: characteristicWrite 与 currentPeripheral 已就绪;无响应写不产生逐包应答,写入即返回。

reConnectWithUUID(uuid: String)

按系统 UUID 重连:清空 reconnectMac、设置 reconnectUUID、启动扫描与超时计时。

reConnectWithMac(mac: String)

按 MAC 重连:清空 reconnectUUID、设置 reconnectMac、启动扫描与超时计时。MAC 通常由广播包厂商数据解析(kCBAdvDataManufacturerData)。

失败模式、边界情况与并发

  • 升级中断开连接:didDisconnectPeripheral 后 SDK 返回 JL_OTAResultDisconnect,示例策略为不自动重连、交由用户处理;JL_OTAResultReconnect / JL_OTAResultReconnectWithMacAddr 才触发自动回连。
  • 设备重启后广播变化:OTA 第一阶段升级后设备会重启并可能更换广播名,系统 UUID 可能保留也可能失效,因此 SDK 提供两种回连标识(UUID 与 MAC),App 需同时实现两条路径。
  • 命令超时:JL_OTAResultFailCmdTimeout 采用退避重试(最多 3 次、延时递增),防止高频重试加剧链路拥塞;重试仍失败则停止。
  • 低电量:JL_OTAResultLowPower 直接放弃,避免升级中途断电变砖。
  • 并发写入:示例采用 .withoutResponse 串行分片写入,无显式发送队列;在升级大流量场景下,建议由 JL_OTAManager 的流控(等待 cmdOtaDataReceive 回包再发下一帧)天然限速,App 侧不应自行并发写入多条 OTA 数据。
  • 空特征/空外设:write(data:) 以 guard let 兜底,characteristicWrite 或 currentPeripheral 缺失时静默返回,避免崩溃;调试时应通过 JLLogManager 确认服务发现时序。

性能与运维注意事项

  • 吞吐关键在分片:无响应写 + 按 maximumWriteValueLength 分片是 OTA 速度的决定因素;若自行实现,勿用 .withResponse 或固定 20 字节 MTU 硬分片。
  • 日志可观测性:重连入口(reConnectWithUUID / reConnectWithMac)均打印 .DEBUG 日志,包含 UUID/MAC,配合 测试调试 文档可快速定位断连原因。
  • 扫描功耗:startScan() 后务必在连接成功或超时后 stopScan();重连路径用 startTimeout() 兜底,防止扫描无限期运行。

扩展点

  • JL_OTAManagerDelegate:otaUpgradeResult(_:progress:)、otaDataSend(_:)、otaCancel()、otaFeatureResult(_:) 是 App 与 OTA 引擎的全部交互面,可在此接入 UI 进度条、重连弹窗等。
  • JLHashHandlerDelegate:hash(onPairOutputData:) 提供认证输出回调,App 可替换写入实现(例如写入前加密、日志记录)。
  • RxSwift 数据流:subNotifyInitSubject(订阅完成事件)与 subNotifySubject(上行数据流)是 BleManager 暴露的响应式扩展点,便于与既有 Rx 架构整合;非 Rx 工程可直接在 delegate 回调中实现等价逻辑。

Related Links

  • OTA 升级开发示例(原生 CoreBluetooth 接入完整示例)
  • MiniSingleDemo BleManager.swift(原生连接管理器实现)
  • 使用 JL_BLEKit.xcframework 蓝牙连接方式(SDK 内置连接)
  • GATT Over EDR 连接
  • JL_OTAManager API 说明
  • SDK 常见问题答疑(重连/超时/后台权限)
Prev
设备扫描与广播发现
Next
JL_BLEKit SDK 连接