设备固件更新
设备 OTA 用于升级 AIBuds 设备的主固件,与用于升级摄像头模块固件的 Camera OTA 是两套独立流程。
宿主 App 需要先自行完成版本检查、固件下载、完整性校验以及设备型号匹配,再将兼容的本地固件包交给 SDK。SDK 负责传输并安装固件,依次回调任务启动结果、0.0 至 1.0 范围内的升级进度,以及包含平均传输速度的最终结果。startHandler 成功仅表示 OTA 任务已启动,升级是否成功应以 completionHandler 为准。
设备 OTA 升级流程
宿主 App 确认固件包和升级条件后,由 SDK 启动任务、传输固件并完成升级。
前提条件
- 设备已连接,且对应的设备对象实现了
DeviceOtaAPI协议。 - 通过
otaProtocolCapability判断设备支持的协议,不要根据固件文件名猜测。 - 使用 FitCloud Pro 或杰理 OTA 时,请在连接设备前安装并注册对应的 OTA 插件。
- 设备电量已达到
otaBatteryLimit指定的最低百分比。 filePath指向完整、可读取且与当前设备匹配的固件包。- 升级完成前,请保持 App 处于活跃状态,并确保设备连接稳定。
使用 AI 辅助实现
让 AI 帮助实现此工作流
使用官方“更新 AIBuds 设备固件”技能,根据你的 App 完成实现。
请阅读并遵循 https://docs-aibuds.github.io/zh-Hans/skills/update-aibuds-firmware,使用该技能在当前 iOS 项目中完成“更新 AIBuds 设备固件”,并验证结果。API 参考
框架
AIBuds.xcframework
导入
- Swift
- Objective-C
import AIBuds
import AIBudsFoundation#import <AIBuds/AIBuds-Swift.h>
#import <AIBuds/AIBuds.h>协议
- Swift
- Objective-C
/// The protocol for device OTA upgrade API.
protocol DeviceOtaAPI: DeviceAPI {
/// The OTA protocol capability reported by the device.
/// Defaults to `.abmate` when the device does not report this capability.
var otaProtocolCapability: OtaProtocolCapability { get }
/// OTA battery limit, 0...100, unit: percent.
var otaBatteryLimit: Int { get }
/// Start OTA upgrade.
/// - Parameters:
/// - filePath: Upgrade file path.
/// - startHandler: Upgrade start callback.
/// - success: Whether the OTA task started successfully.
/// - error: Failure information, or `nil` if the task started.
/// - progressHandler: Upgrade progress callback.
/// - progress: Progress value in the range `0.0...1.0`.
/// - completionHandler: Final upgrade completion callback.
/// - success: Whether the upgrade succeeded.
/// - avgSpeed: Average transfer speed in kB/s.
/// - error: Failure information, or `nil` if the upgrade succeeded.
func startOta(
withFilePath filePath: String,
startHandler: AIBudsOtaStartCompletionHandler?,
progressHandler: AIBudsOtaProgressHandler?,
completionHandler: AIBudsOtaCompletionHandler?
)
/// Start OTA upgrade with an explicit transfer protocol configuration.
/// - Parameters:
/// - filePath: Upgrade file path.
/// - configuration: OTA protocol configuration.
/// - startHandler: Upgrade start callback.
/// - success: Whether the OTA task started successfully.
/// - error: Failure information, or `nil` if the task started.
/// - progressHandler: Upgrade progress callback.
/// - progress: Progress value in the range `0.0...1.0`.
/// - completionHandler: Final upgrade completion callback.
/// - success: Whether the upgrade succeeded.
/// - avgSpeed: Average transfer speed in kB/s.
/// - error: Failure information, or `nil` if the upgrade succeeded.
func startOta(
withFilePath filePath: String,
configuration: OtaConfiguration,
startHandler: AIBudsOtaStartCompletionHandler?,
progressHandler: AIBudsOtaProgressHandler?,
completionHandler: AIBudsOtaCompletionHandler?
)
}/// The protocol for device OTA upgrade API.
@protocol AIBudsDeviceOtaAPI <AIBudsDeviceAPI>
/// The OTA protocol capability reported by the device.
/// Defaults to `AIBudsOtaProtocolCapabilityAbmate` when the device does not report it.
@property(nonatomic, readonly) AIBudsOtaProtocolCapability otaProtocolCapability;
/// OTA battery limit, 0...100, unit: percent.
@property(nonatomic, readonly) NSInteger otaBatteryLimit;
/// Start OTA upgrade from a local firmware path.
///
/// - Parameters:
/// - filePath: The readable local firmware file path.
/// - startHandler: Called when the OTA start attempt completes.
/// - success: `YES` if the OTA task started; otherwise `NO`.
/// - error: Failure information, or `nil` if the task started.
/// - progressHandler: Called when OTA progress changes.
/// - progress: Progress in the range `0.0...1.0`.
/// - completionHandler: Called when the OTA operation finishes.
/// - success: `YES` if the upgrade succeeded; otherwise `NO`.
/// - avgSpeed: Average transfer speed in kB/s.
/// - error: Failure information, or `nil` if the upgrade succeeded.
- (void)startOtaWithFilePath:(NSString *_Nonnull)filePath
startHandler:(AIBudsOtaStartCompletionHandler _Nullable)startHandler
progressHandler:(AIBudsOtaProgressHandler _Nullable)progressHandler
completionHandler:(AIBudsOtaCompletionHandler _Nullable)completionHandler;
/// Start OTA upgrade with an explicit transfer protocol configuration.
///
/// - Parameters:
/// - filePath: The readable local firmware file path.
/// - configuration: The OTA protocol configuration required by the device.
/// - startHandler: Called when the OTA start attempt completes.
/// - success: `YES` if the OTA task started; otherwise `NO`.
/// - error: Failure information, or `nil` if the task started.
/// - progressHandler: Called when OTA progress changes.
/// - progress: Progress in the range `0.0...1.0`.
/// - completionHandler: Called when the OTA operation finishes.
/// - success: `YES` if the upgrade succeeded; otherwise `NO`.
/// - avgSpeed: Average transfer speed in kB/s.
/// - error: Failure information, or `nil` if the upgrade succeeded.
- (void)startOtaWithFilePath:(NSString *_Nonnull)filePath
configuration:(AIBudsOtaConfiguration *_Nonnull)configuration
startHandler:(AIBudsOtaStartCompletionHandler _Nullable)startHandler
progressHandler:(AIBudsOtaProgressHandler _Nullable)progressHandler
completionHandler:(AIBudsOtaCompletionHandler _Nullable)completionHandler;
@end另请参阅 API Reference 中的 otaProtocolCapability、otaBatteryLimit,以及 startOta 的两个重载。
设备支持的 OTA 协议
设备就绪后读取 otaProtocolCapability,并据此确定可用的 OTA 协议。
| Swift | Objective-C | 原始值 | 支持的协议 |
|---|---|---|---|
.none | AIBudsOtaProtocolCapabilityNone | -1 | 设备未声明支持 OTA。 |
.abmate | AIBudsOtaProtocolCapabilityAbmate | 0 | ABMate。设备未上报该能力时,SDK 也默认按 ABMate 处理。 |
.fitcloudPro | AIBudsOtaProtocolCapabilityFitcloudPro | 1 | FitCloud Pro。需要 FitCloud Pro 插件。 |
.abmateAndFitcloudPro | AIBudsOtaProtocolCapabilityAbmateAndFitcloudPro | 2 | 同时支持 ABMate 和 FitCloud Pro;界面中只应展示已注册插件的协议选项。 |
.jieli | AIBudsOtaProtocolCapabilityJieli | 3 | 杰理 OTA(single-bank 模式)。需要杰理插件。 |
OTA 配置
调用带配置参数的重载时,可通过 OtaConfiguration 选择 BLE OTA 协议。otaProtocol 属性的默认值为 .abmate。
| Swift | Objective-C | 原始值 | 含义 |
|---|---|---|---|
.abmate | AIBudsOtaProtocolKindAbmate | 0 | ABMate OTA 协议。 |
.fitcloudPro | AIBudsOtaProtocolKindFitcloudPro | 1 | FitCloud Pro OTA 协议。 |
.jieli | AIBudsOtaProtocolKindJieli | 2 | 杰理 OTA 协议(single-bank 模式)。 |
不要根据固件文件名猜测协议。请根据当前设备的能力以及产品采用的升级方案选择协议。
可选的 OTA 插件
FitCloud Pro 和杰理 OTA 分别作为独立的 CocoaPods 子组件(subspec)提供。请在连接设备前注册相应插件,以便 SDK 发现并订阅升级所需的 BLE 特征。通过 AIBudsSDK/AllInOne 集成时,这两个插件会自动安装并注册。
pod 'AIBudsSDK/FitCloudProOTA'
pod 'AIBudsSDK/JieliOTA'import AIBuds
import AIBudsFitCloudProOTA
import AIBudsJieliOTA
AIBudsSDK.registerOtaPlugin(FitCloudProOtaSDK.otaPlugin)
AIBudsSDK.registerOtaPlugin(JieliOtaSDK.otaPlugin)采用模块化集成时,只需注册产品实际使用的协议插件。对同一个 OtaProtocolKind 重复注册时,新插件会替换原插件。可以通过 AIBudsSDK.otaPlugin(for:) 检查插件是否可用,也可以通过 AIBudsSDK.removeOtaPlugin(for:) 移除已注册的插件。
返回值
两个重载均无直接返回值。startHandler 用于确认 OTA 任务能否成功启动,progressHandler 持续返回升级进度,completionHandler 返回最终升级结果和平均传输速度。
使用示例
- Swift
- Objective-C
guard let device = device as? DeviceOtaAPI else { return }
guard deviceBatteryPercent >= device.otaBatteryLimit else {
print("Charge the device before updating")
return
}
device.startOta(
withFilePath: firmwareURL.path,
startHandler: { success, error in
if !success { print(error?.localizedDescription ?? "OTA failed to start") }
},
progressHandler: { progress in
print("OTA: \(Int(progress * 100))%")
},
completionHandler: { success, averageSpeed, error in
print(
success
? "OTA completed at \(averageSpeed) kB/s"
: (error?.localizedDescription ?? "OTA failed"))
})id<AIBudsDeviceOtaAPI> device = (id<AIBudsDeviceOtaAPI>)self.device;
if (![device conformsToProtocol:@protocol(AIBudsDeviceOtaAPI)])
return;
[device startOtaWithFilePath:firmwareURL.path
startHandler:^(BOOL success, NSError *_Nullable error) {
if (!success)
NSLog(@"OTA failed to start: %@", error.localizedDescription);
}
progressHandler:^(CGFloat progress) {
NSLog(@"OTA: %.0f%%", progress * 100);
}
completionHandler:^(BOOL success, CGFloat averageSpeed, NSError *_Nullable error) {
if (success) {
NSLog(@"OTA completed at %.2f kB/s", averageSpeed);
} else {
NSLog(@"OTA failed: %@", error.localizedDescription);
}
}];指定 OTA 协议
只有在 App 能够明确确定当前设备所需的 OTA 协议时,才应调用带配置参数的重载。
- Swift
- Objective-C
let configuration = OtaConfiguration()
configuration.otaProtocol = .fitcloudPro
device.startOta(
withFilePath: firmwareURL.path,
configuration: configuration,
startHandler: { success, error in
if !success {
print(error?.localizedDescription ?? "OTA failed to start")
}
},
progressHandler: { progress in
print("OTA: \(Int(progress * 100))%")
},
completionHandler: { success, averageSpeed, error in
print(
success
? "OTA completed at \(averageSpeed) kB/s"
: (error?.localizedDescription ?? "OTA failed"))
}
)AIBudsOtaConfiguration *configuration = [[AIBudsOtaConfiguration alloc] init];
configuration.otaProtocol = AIBudsOtaProtocolKindFitcloudPro;
[device startOtaWithFilePath:firmwareURL.path
configuration:configuration
startHandler:^(BOOL success, NSError *_Nullable error) {
if (!success)
NSLog(@"OTA failed to start: %@", error.localizedDescription);
}
progressHandler:^(CGFloat progress) {
NSLog(@"OTA: %.0f%%", progress * 100);
}
completionHandler:^(BOOL success, CGFloat averageSpeed, NSError *_Nullable error) {
if (success) {
NSLog(@"OTA completed at %.2f kB/s", averageSpeed);
} else {
NSLog(@"OTA failed: %@", error.localizedDescription);
}
}];错误处理
OTA 错误使用 AIBudsSDK.OtaErrorDomain 和 SdkOtaErrorCode。
| 代码 | 常见情况 |
|---|---|
unknown | SDK 无法识别出更具体的错误类型。 |
otaTaskAlreadyRunning | 已有另一个 OTA 任务正在运行。 |
otaTaskCreateFailedDueToFileNotFound | 本地固件路径不存在。 |
otaTaskStartFailedDueToFileReadError, otaTaskStartFailedDueToFileHandleCreateError | 无法打开或读取固件包。 |
otaTaskStartFailedDueToInvalidFileHashData | 固件哈希数据无效。 |
otaTaskStartFailedDueToGetOtaInfoError | 无法获取所需 OTA 元数据。 |
otaTaskStartFailedDueToInvalidOffsetAddress, otaTaskStartFailedDueToInvalidBlockSize | 传输元数据无效。 |
otaTaskStartFailedDueToNotAllowUpdate | 设备在当前状态下不允许升级。 |
otaTaskSendDataFailedDueToFileHandleIsNil, otaTaskSendDataFailedDueToSeekFileHandleFailed, otaTaskSendDataFailedDueToReadFileDataFailed, otaTaskSendDataFailedDueToOtaInfoIsNil | SDK 无法继续读取或发送固件数据。 |
otaTaskFailedDueToDeviceReportKeyMismatch, otaTaskFailedDueToDeviceReportCrcError, otaTaskFailedDueToDeviceReportSeqError, otaTaskFailedDueToDeviceReportDataLengthError | 设备拒绝接收数据,或报告校验、数据序号或长度异常。 |
otaTaskFailedDueToDeviceDisconnect, otaTaskFailedDueToTimeout | 设备断开连接或操作超时。 |
请区分任务启动失败(startHandler)和传输开始后的升级失败。不要直接使用尚未验证的固件包自动重试;重试前应重新检查设备型号、固件版本、固件包完整性、设备电量、协议选择以及连接状态。
最佳实践
- 调用 SDK 前,由 App 完成版本检查、固件下载、签名或完整性校验,以及设备型号兼容性检查。
- 发起升级前再次检查
otaBatteryLimit,不要只在展示升级界面时检查一次。 - 避免设备 OTA、Camera OTA、媒体文件导入或其他耗时较长的设备操作并发执行。
- 回调不保证在主队列执行;更新 UI 时请主动切换到主队列。
startHandler仅用于确认任务已启动;只有completionHandler返回成功后,才能将升级结果标记为成功。- 整个升级过程中保持 App 活跃并确保设备连接稳定;设备重新连接后,再读取并确认固件版本。
注意事项
- 升级进度位于
0.0...1.0范围内。UI 展示时可以将数值限制在该范围内,但不要改写 SDK 返回的原始结果。 avgSpeed仅在最终完成回调中提供,单位为 kB/s。OtaConfiguration.otaProtocol默认为.abmate。选择.fitcloudPro或.jieli前,请确认otaProtocolCapability声明支持该协议,并且对应插件已安装。- SDK 目前未提供取消 OTA 的公开方法。Demo 中的 Cancel 按钮只会重置本地 UI 状态,并不会取消 SDK 正在执行的升级任务。