You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BLE设备无数据时Runmefit SDK回调未执行致App崩溃的解决咨询

方案1:修复闭包内的强制转换与空值校验

将闭包内的强制类型转换改为可选绑定,同时提前过滤空数据场景,避免无意义的SDK调用:

public func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    print("Received: \(String(describing: characteristic.value))")
    
    guard let writeCharacter = writeCharacter else {
        print("No write characteristic found")
        return
    }

    // 提前过滤空数据,直接通知RN侧无数据
    guard let characteristicValue = characteristic.value, !characteristicValue.isEmpty else {
        let emptyDataDict: [String: Any] = [
            ST_RevType_Key: NSNumber(value: REV_TYPE.noData.rawValue), // 需确保枚举有对应值,无则自定义临时值
            ST_ErrorType_Key: NSNumber(value: ERROR_TYPE.success.rawValue)
        ]
        NotificationCenter.default.post(
            name: NSNotification.Name(Nof_Revice_Data_Key),
            object: nil,
            userInfo: emptyDataDict
        )
        return
    }
    
    let nsError = error as NSError? ?? NSError(domain: "", code: 0, userInfo: nil)
    
    STBlueToothData.sharedInstance().notifyRunmefit(
        peripheral,
        writeCharacter: writeCharacter,
        characteristic: characteristic,
        error: nsError,
        complete: { (error, revType, errorType, responseObject) in
            // 安全转换error参数,避免nil强制转NSError崩溃
            guard let nsError = error as NSError? else {
                let resultDict: [String: Any] = [
                    ST_RevType_Key: NSNumber(value: revType.rawValue),
                    ST_ErrorType_Key: NSNumber(value: errorType.rawValue)
                ]
                NotificationCenter.default.post(
                    name: NSNotification.Name(Nof_Revice_Data_Key),
                    object: responseObject,
                    userInfo: resultDict
                )
                return
            }
            
            if nsError.code != 0 {
                print("Error: \(nsError)")
            } else {
                let resultDict: [String: Any] = [
                    ST_RevType_Key: NSNumber(value: revType.rawValue),
                    ST_ErrorType_Key: NSNumber(value: errorType.rawValue)
                ]
                
                NotificationCenter.default.post(
                    name: NSNotification.Name(Nof_Revice_Data_Key),
                    object: responseObject,
                    userInfo: resultDict
                )
            }
        }
    )
}

方案2:添加回调超时机制

用DispatchWorkItem实现超时逻辑,避免SDK回调永远不执行导致的未知问题:

public func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    print("Received: \(String(describing: characteristic.value))")
    
    guard let writeCharacter = writeCharacter else {
        print("No write characteristic found")
        return
    }

    guard let characteristicValue = characteristic.value, !characteristicValue.isEmpty else {
        // 空数据处理逻辑同方案1
        let emptyDataDict: [String: Any] = [
            ST_RevType_Key: NSNumber(value: REV_TYPE.noData.rawValue),
            ST_ErrorType_Key: NSNumber(value: ERROR_TYPE.success.rawValue)
        ]
        NotificationCenter.default.post(
            name: NSNotification.Name(Nof_Revice_Data_Key),
            object: nil,
            userInfo: emptyDataDict
        )
        return
    }
    
    let nsError = error as NSError? ?? NSError(domain: "", code: 0, userInfo: nil)
    
    // 创建超时任务
    let timeoutWorkItem = DispatchWorkItem { [weak self] in
        guard let self = self else { return }
        print("notifyRunmefit callback timeout")
        // 发送超时通知给RN侧
        let timeoutDict: [String: Any] = [
            ST_RevType_Key: NSNumber(value: REV_TYPE.timeout.rawValue), // 需确保枚举有对应值
            ST_ErrorType_Key: NSNumber(value: ERROR_TYPE.timeout.rawValue)
        ]
        NotificationCenter.default.post(
            name: NSNotification.Name(Nof_Revice_Data_Key),
            object: nil,
            userInfo: timeoutDict
        )
    }
    
    // 3秒后触发超时(可根据需求调整时长)
    DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: timeoutWorkItem)
    
    STBlueToothData.sharedInstance().notifyRunmefit(
        peripheral,
        writeCharacter: writeCharacter,
        characteristic: characteristic,
        error: nsError,
        complete: { [weak self] (error, revType, errorType, responseObject) in
            // 回调执行时取消超时任务
            timeoutWorkItem.cancel()
            
            guard let self = self else { return }
            
            // 安全处理参数逻辑同方案1
            guard let nsError = error as NSError? else {
                let resultDict: [String: Any] = [
                    ST_RevType_Key: NSNumber(value: revType.rawValue),
                    ST_ErrorType_Key: NSNumber(value: errorType.rawValue)
                ]
                NotificationCenter.default.post(
                    name: NSNotification.Name(Nof_Revice_Data_Key),
                    object: responseObject,
                    userInfo: resultDict
                )
                return
            }
            
            if nsError.code != 0 {
                print("Error: \(nsError)")
            } else {
                let resultDict: [String: Any] = [
                    ST_RevType_Key: NSNumber(value: revType.rawValue),
                    ST_ErrorType_Key: NSNumber(value: errorType.rawValue)
                ]
                
                NotificationCenter.default.post(
                    name: NSNotification.Name(Nof_Revice_Data_Key),
                    object: responseObject,
                    userInfo: resultDict
                )
            }
        }
    )
}

方案3:优化闭包生命周期管理

在闭包捕获列表中添加[weak self],避免循环引用导致的内存泄漏,同时确保闭包内访问self时的安全性。


额外注意事项

  • 如果REV_TYPE和ERROR_TYPE没有对应noData/timeout的枚举值,可自定义临时值传递给RN侧,或联系SDK厂商补充枚举定义
  • 测试空数据场景时,需确认BLE设备确实返回空的特征值,避免误判
  • 可在didUpdateValueFor方法中添加更多日志,排查SDK的异常行为

内容的提问来源于stack exchange,提问作者Jonas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 21:35:54