跳到主要内容

错误处理

SDK 所有异步接口均通过 NSError 返回错误信息。本文介绍错误的结构、完整错误码及最佳实践。

错误结构​

SDK 返回的 NSError 包含以下字段:

字段说明
domain错误域,格式为 TS[模块名]ErrorDomain,如 TSBleErrorDomain
code错误码(见下方分类)
userInfo[NSLocalizedDescriptionKey]可读的错误描述
userInfo[NSUnderlyingErrorKey]底层原始错误(如有)

回调约定​

SDK 的回调有两种模式:

1. TSCompletionBlock(成功/失败二值)​

typedef void(^TSCompletionBlock)(BOOL isSuccess, NSError * _Nullable error);
[[TopStepComKit sharedInstance].bleConnector disconnectCompletion:^(BOOL isSuccess, NSError *error) {
if (isSuccess) {
// 操作成功
} else {
[self handleError:error];
}
}];

2. 数据回调(仅 error 参数)​

[[TopStepComKit sharedInstance].heartRate getHistoryDataFrom:startDate to:endDate
completion:^(NSArray *records, NSError *error) {
if (error) {
[self handleError:error];
return;
}
// 正常处理 records
}];

通用错误码(TSErrorCode)​

适用于所有模块,定义在 TSErrorEnum.h。

系统错误(1001–1004)​

枚举值Code含义
eTSErrorUnknown1001未知错误
eTSErrorSDKInitFailed1002SDK 初始化失败
eTSErrorLicenseIncorrect1003SDK 证书错误
eTSErrorSDKConfigError1004SDK 配置错误

设备状态错误(2001–2006)​

枚举值Code含义处理建议
eTSErrorNotReady2001设备未就绪等待连接完成后重试
eTSErrorLowBattery2002设备电量过低(< 30%)提示用户充电
eTSErrorUnConnected2003设备未连接提示用户重新连接设备
eTSErrorNotSupport2004暂不支持此功能隐藏对应功能入口
eTSErrorNoSpace2005设备空间不足提示用户清理设备存储
eTSErrorIsBusy2006设备繁忙稍后重试

参数错误(3001–3004)​

枚举值Code含义
eTSErrorInvalidParam3001参数不存在
eTSErrorParamError3002参数错误
eTSErrorInvalidTypeError3003参数类型错误
eTSErrorParamSizeError3004参数大小错误

数据操作错误(4001–4004)​

枚举值Code含义
eTSErrorDataGetFailed4001数据获取失败
eTSErrorDataSetFailed4002数据设置失败
eTSErrorDataFormatError4003数据格式错误
eTSErrorDataIsEmpty4004数据为空

任务错误(5001–5003)​

枚举值Code含义处理建议
eTSErrorPreTaskExecuting5001任务执行中(如 OTA)等待任务完成后重试
eTSErrorTaskExecutionFailed5002任务执行失败提示用户重试
eTSErrorTaskNotStarted5003任务未开始检查调用时序

通信错误(6001–6008)​

枚举值Code含义处理建议
eTSErrorTimeoutError6001通信超时重试操作
eTSErrorTransmissionInterrupted6002数据传输中断检查设备距离,重试
eTSErrorSignalInterference6003信号干扰或丢失减少干扰源,重试
eTSErrorPacketLoss6004数据包丢失重试操作
eTSErrorProtocolMismatch6005通信协议不匹配升级 SDK 或固件
eTSErrorConnectionReset6006连接被对方重置重新连接设备
eTSErrorBufferOverflow6007通信缓冲区溢出降低发送频率
eTSErrorChannelBusy6008通信通道繁忙稍后重试

用户操作错误(7001)​

枚举值Code含义
eTSErrorUserCancelled7001用户取消操作

蓝牙连接错误码(TSBleConnectionError)​

蓝牙专属错误,定义在 TSErrorEnum.h,通过 error.code 获取。

参数错误(9001–9004)​

枚举值Code含义
eTSBleErrorInvalidRandomCode9001二维码参数错误
eTSBleErrorInvalidUserId9002用户 ID 参数错误
eTSBleErrorInvalidParam9003参数错误
eTSBleErrorInvalidHandle9004无效句柄

通用错误(9101–9106)​

枚举值Code含义处理建议
eTSBleErrorUnknown9101未知错误提示用户重试
eTSBleErrorTimeout9102连接超时检查设备是否在范围内,重试
eTSBleErrorDisconnected9103连接意外断开提示用户重新连接
eTSBleErrorOutOfSpace9104存储空间不足提示用户清理设备
eTSBleErrorUUIDNotAllowed9105UUID 不被允许检查设备兼容性
eTSBleErrorAlreadyAdvertising9106已在广播中等待广播结束后重试

权限和系统错误(9201–9206)​

枚举值Code含义处理建议
eTSBleErrorBluetoothOff9201蓝牙未开启提示用户打开系统蓝牙
eTSBleErrorBluetoothUnsupported9202蓝牙不支持提示设备不支持蓝牙
eTSBleErrorPermissionDenied9203缺少蓝牙权限引导用户前往「设置」开启蓝牙权限
eTSBleErrorSystemServiceUnavailable9204系统蓝牙服务不可用提示用户重启手机
eTSBleErrorBluetoothStateUnknown9205蓝牙状态未知等待蓝牙就绪后重试
eTSBleErrorBluetoothResetting9206蓝牙正在重置等待重置完成后重试

连接过程错误(9301–9308)​

枚举值Code含义处理建议
eTSBleErrorConnectionFailed9301连接失败重试连接
eTSBleErrorGattConnectFailed9302GATT 连接失败重启蓝牙后重试
eTSBleErrorDeviceOutOfRange9303设备不在范围内靠近设备后重试
eTSBleErrorWeakSignal9304信号太弱靠近设备后重试
eTSBleErrorSignalLost9305信号丢失靠近设备后重试
eTSBleErrorConnectionLimitReached9306连接数达到限制断开其他连接后重试
eTSBleErrorUnknownDevice9307未知设备重新扫描并选择设备
eTSBleErrorOperationNotSupported9308操作不支持检查设备固件版本

认证错误(9404–9413、9499)​

枚举值Code含义处理建议
eTSBleErrorEncryptionFailed9404加密失败重新绑定设备
eTSBleErrorPeerRemovedPairingInfo9405配对信息被移除重新绑定设备
eTSBleErrorEncryptionTimeout9406加密超时重试连接
eTSBleErrorUserIdMismatch9407用户 ID 不匹配检查 userId 参数
eTSBleErrorBindCancelledByUser9408用户取消绑定引导用户重新操作
eTSBleErrorBindTimeout9409绑定超时重新发起绑定
eTSBleErrorClassicBluetoothNotConnected9410经典蓝牙未连接检查经典蓝牙连接状态
eTSBleErrorLowBatteryCannotDeleteData9411电量不足无法删除数据提示用户充电
eTSBleErrorDeviceFactoryResetting9412设备正在恢复出厂等待恢复完成后重试
eTSBleErrorFactoryResetRequired9413需要恢复出厂才能重新绑定提示用户在设备上恢复出厂设置
eTSBleErrorAuthenticationUnknown9499认证失败(未知原因)重试连接

设备状态错误(9501–9506)​

枚举值Code含义处理建议
eTSBleErrorConnectedByOthers9501设备已被其他设备连接提示用户断开其他连接
eTSBleErrorDeviceAlreadyBound9502设备已被绑定提示用户先解绑
eTSBleErrorLowBattery9503设备电量过低提示用户充电
eTSBleErrorDFUMode9504设备进入 DFU 模式等待 DFU 完成或重启设备
eTSBleErrorDeviceSleeping9505设备处于睡眠模式唤醒设备后重试
eTSBleErrorTooManyPairedDevices9506配对设备过多删除部分配对记录

服务和协议错误(9601–9605)​

枚举值Code含义处理建议
eTSBleErrorPeripheralNotFound9601未找到对应外设重新扫描设备
eTSBleErrorServiceNotFound9602未找到所需服务检查设备固件版本
eTSBleErrorCharacteristicNotFound9603特征值未找到检查设备固件版本
eTSBleErrorProtocolVersionMismatch9604协议版本不匹配升级 SDK 或固件
eTSBleErrorMtuNegotiationFailed9605MTU 协商失败重试连接

用户操作(9701–9702)​

枚举值Code含义
eTSBleErrorDisconnectedByUser9701用户主动断开连接
eTSBleErrorCancelledByUser9702用户取消连接

扫描结束原因(TSScanCompletionReason)​

枚举值含义处理建议
eTSScanCompleteReasonTimeout扫描超时提示未找到设备,可重新扫描
eTSScanCompleteReasonBleNotReady蓝牙未就绪等待蓝牙初始化完成后重试
eTSScanCompleteReasonPermissionDenied权限被拒绝引导用户开启蓝牙权限
eTSScanCompleteReasonUserStopped用户主动停止正常结束,无需处理
eTSScanCompleteReasonSystemError系统错误重启蓝牙后重试

功能不支持检查​

调用功能接口前,先用 isSupport 检查设备是否支持:

id<TSHeartRateInterface> heartRate = [TopStepComKit sharedInstance].heartRate;

if (![heartRate isSupport]) {
TSLog(@"当前设备不支持心率功能");
return;
}

[heartRate startMeasureWithParam:nil ...];

统一错误处理​

建议封装一个统一的错误处理方法:

- (void)handleSDKError:(NSError *)error context:(NSString *)context {
if (!error) return;

TSLog(@"[%@] 错误 domain=%@ code=%ld: %@",
context,
error.domain,
(long)error.code,
error.localizedDescription);

switch (error.code) {
// 权限/蓝牙状态类 → 引导用户操作
case eTSBleErrorPermissionDenied:
case eTSBleErrorBluetoothOff:
[self showBluetoothSettingsAlert];
break;

// 超时/信号类 → 可重试
case eTSBleErrorTimeout:
case eTSBleErrorSignalLost:
case eTSErrorTimeoutError:
[self retryWithDelay];
break;

// 设备繁忙 → 稍后重试
case eTSErrorIsBusy:
case eTSBleErrorChannelBusy:
[self scheduleRetry];
break;

// 功能不支持 → 隐藏入口
case eTSErrorNotSupport:
[self hideUnsupportedFeature:context];
break;

default:
[self showErrorAlert:error.localizedDescription];
break;
}
}

权限错误处理​

- (void)showBluetoothSettingsAlert {
UIAlertController *alert = [UIAlertController
alertControllerWithTitle:@"蓝牙未授权"
message:@"请前往「设置 → 隐私 → 蓝牙」开启蓝牙权限"
preferredStyle:UIAlertControllerStyleAlert];

[alert addAction:[UIAlertAction actionWithTitle:@"去设置"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}]];

[alert addAction:[UIAlertAction actionWithTitle:@"取消"
style:UIAlertActionStyleCancel
handler:nil]];

[self presentViewController:alert animated:YES completion:nil];
}

注意事项​

  1. 不要忽略 error 参数:即使 isSuccess = YES,仍应先判断 error 再判断 isSuccess
  2. 在主线程更新 UI:SDK 所有回调均在主线程执行,可直接操作 UI
  3. 区分可恢复错误和不可恢复错误:超时类错误可重试,权限类错误需引导用户操作,硬件不支持类错误应隐藏对应功能入口
  4. 日志上报:建议将 error.domain、error.code 上报到后端,便于排查问题