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

React Native BLE Manager:OTA升级写入回调追踪问题

React Native Ble Manager OTA升级:追踪单条写入回调与进度计算

方案一:修改iOS原生代码搭建桥接回调

既然你已经在iOS ObjC代码中观察到每次写入都会触发回调,可直接在原生层添加事件通知,将写入结果传递到JavaScript层:

1. 修改iOS原生代码(react-native-ble-manager)

找到BleManager.m中的peripheral:didWriteValueForCharacteristic:error:方法,在原有日志代码后添加事件发送逻辑:

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    // 保留原有日志
    NSLog(@"Write completed for characteristic %@", characteristic.UUID);
    
    // 组装事件数据,传递外设ID、特征UUID、错误信息和写入字节数
    NSDictionary *eventData = @{
        @"peripheralId": peripheral.identifier.UUIDString,
        @"characteristicUUID": characteristic.UUID.UUIDString,
        @"error": error ? error.localizedDescription : [NSNull null],
        @"bytesWritten": @(characteristic.value.length)
    };
    
    // 发送事件到JS层
    [self sendEventWithName:@"BleManagerWriteCompleted" body:eventData];
}

注:react-native-ble-manager的核心类默认已实现事件发射器能力,无需额外调整继承关系。

2. JavaScript层监听事件

在RN代码中通过NativeEventEmitter监听原生发送的写入完成事件,实时更新进度:

import { NativeEventEmitter, Platform, useEffect, useState } from 'react-native';
import BleManager from 'react-native-ble-manager';

const BleManagerEmitter = new NativeEventEmitter(BleManager);

// 进度状态管理
const [otaProgress, setOtaProgress] = useState(0);
let totalOtaBytes = 0;
let sentBytes = 0;

// 初始化OTA总字节数(从固件数据中获取)
const initOTA = (firmwareData) => {
  totalOtaBytes = firmwareData.length;
  sentBytes = 0;
  setOtaProgress(0);
};

// 更新进度逻辑
const updateWriteProgress = (bytes) => {
  sentBytes += bytes;
  const progress = Math.min((sentBytes / totalOtaBytes) * 100, 100);
  setOtaProgress(progress.toFixed(2));
};

// 监听iOS写入完成事件
useEffect(() => {
  let writeSubscription;
  if (Platform.OS === 'ios') {
    writeSubscription = BleManagerEmitter.addListener(
      'BleManagerWriteCompleted',
      (event) => {
        // 过滤当前OTA操作的外设和特征(避免其他BLE写入干扰)
        if (event.peripheralId === yourPeripheralId && event.characteristicUUID === yourOtaCharUUID) {
          updateWriteProgress(event.bytesWritten);
        }
      }
    );
  }

  // 组件卸载时取消订阅
  return () => writeSubscription?.remove();
}, []);

3. 保留修改的技巧

直接修改node_modules代码会在依赖更新后丢失,推荐用patch-package保存补丁:

  1. 修改完原生代码后,运行npx patch-package react-native-ble-manager
  2. 项目根目录生成patches文件夹,将补丁文件提交到代码仓库
  3. 其他开发者安装依赖后,执行npx patch-package即可自动应用修改

方案二:JS层手动分块发送(无需修改原生)

如果不想改动原生库,可将OTA数据按MTU大小拆分,逐块调用BleManager.write,每块写入完成后更新进度:

const sendOTAData = async (peripheralId, charUUID, firmwareData, mtuSize) => {
  // MTU减去BLE协议头,得到实际可写入的字节数
  const chunkSize = mtuSize - 3;
  const totalChunks = Math.ceil(firmwareData.length / chunkSize);
  let currentChunk = 0;

  for (let i = 0; i < firmwareData.length; i += chunkSize) {
    const chunk = firmwareData.slice(i, i + chunkSize);
    // 等待当前块写入完成再发送下一块
    await BleManager.write(peripheralId, charUUID, chunk);
    currentChunk++;
    const progress = (currentChunk / totalChunks) * 100;
    setOtaProgress(progress.toFixed(2));
  }
};

注意:这种方式依赖BleManager.write的Promise是否会在单块写入完成后才resolve,如果库内部做了批量写入优化,该方法可能无法准确追踪单条写入。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 00:06:11