uni-app ios app写入特征值无法正确返回结果

uni-app ios app写入特征值无法正确返回结果

详细问题描述

(DCloud产品不会有明显的bug,所以你遇到的问题大都是在特定环境下才能重现的问题,请仔细描述你的环境和重现方式,否则DCloud很难排查解决你的问题)

  1. 调用uni.notifyBLECharacteristicValueChange会触发uni.onBLECharacteristicValueChange,并会返回上一次uni.writeBLECharacteristicValue后的返回结果

  2. 在1.9.7之前的版本调用uni.writeBLECharacteristicValue后,不会触发uni.onBLECharacteristicValueChange,但在调用uni.writeBLECharacteristicValue后马上执行uni.readBLECharacteristicValue会触发uni.onBLECharacteristicValueChange,在onBLECharacteristicValueChange中也能获得正确的返回结果;在1.9.7后,调用uni.writeBLECharacteristicValue可以正常触发uni.onBLECharacteristicValueChange,但在onBLECharacteristicValueChange无法返回正确的结果,一直返回空值

  3. uni.writeBLECharacteristicValue在真机调试和越狱包都执行正常,但上架到app store后只能偶尔几次写入成功,但不管是否写入成功都会返回ok,从蓝牙设备的响应可以看出是否写入成功。

  4. 以上问题均只在IOS的app里出现,安卓都正常

重现步骤

示例代码

uni.onBLECharacteristicValueChange(function(e) {
	console.log('onBLECharacteristicValueChange:' + util.buf2hex(e.value).trim());
	Param.stateChangeBack('onBLECharacteristicValueChange:' + util.buf2hex(e.value).trim());
	var result = util.buf2hex(e.value).trim();
	if (Param.writeOk)
		success(result);
});

function writeCharacteristics(cmds) {
	Param.stateChangeBack('writeCharacteristics');
	for (var i = 0; i < cmds.length; i++) {
		console.log('cmd:' + util.buf2hex(cmds[i]));
		Param.stateChangeBack('cmd:' + util.buf2hex(cmds[i]));

		uni.writeBLECharacteristicValue({
			deviceId: Param.lockNo.toUpperCase(),
			serviceId: Param.serviceUuid.toUpperCase(),
			characteristicId: Param.characterUuid.toUpperCase(),
			value: cmds[i],
			success: function(e) {
				console.log('write characteristics success: ' + JSON.stringify(e));
				Param.stateChangeBack('write characteristics success: ' + JSON.stringify(e));
			},
			fail: function(e) {
				console.log('write characteristics failed: ' + JSON.stringify(e));
				Param.stateChangeBack('write characteristics failed: ' + JSON.stringify(e));
				//failure(FailMsg.WRITEVALUEFAIL);
				if (Param.doIndex < 10) {
					Param.doIndex++;
					setTimeout(() => {
						writeCharacteristics(Param.bleCmd);
					}, 200);
				}
			}
		});
	}
}

运行日志:

21:42:38.807  open adapter success: {"errMsg":"openBluetoothAdapter:ok"}
21:42:38.828  startBluetoothDevicesDiscovery success:{"errMsg":"startBluetoothDevicesDiscovery:ok"}
21:42:38.848  onBluetoothAdapterStateChange: {"available":true,"discovering":false}
21:42:38.869  startBluetoothDevicesDiscovery success:{"errMsg":"startBluetoothDevicesDiscovery:ok"}
21:42:38.889  onBluetoothDeviceFound: {"devices":[{"RSSI":-52,"advertisServiceUUIDs":["6E400001-B5A3-F393-E0A9-DEAFD37C1A10"],"deviceId":"9A48D668-F275-8C7A-6BFE-F14D01B49CAA","localName":"000-102","name":"000-102"}]}
21:42:38.930  stopBluetoothDiscovery
21:42:38.971  start connect
21:42:38.992  stop Discovery success: {"errMsg":"stopBluetoothDevicesDiscovery:ok"}
21:42:39.012  onBluetoothAdapterStateChange: {"available":true,"discovering":false}
21:42:39.833  onBLEConnectionStateChange: {"connected":true,"deviceId":"9A48D668-F275-8C7A-6BFE-F14D01B49CAA"}
21:42:39.853  create connection success: {"errMsg":"createBLEConnection:ok"}
21:42:40.899  set notify success: {"errMsg":"notifyBLECharacteristicValueChange:ok"}
21:42:40.919  onBLECharacteristicValueChange:d00ba53030a73030aa3939
21:42:40.940  cmd:d016303461333136346435306164a53535353330
21:42:40.960  cmd:35a7
21:42:40.981  write characteristics success: {"errMsg":"writeBLECharacteristicValue:ok"}
21:42:41.001  onBLECharacteristicValueChange:
21:42:41.042  close connection
21:42:41.063  close connection success: {"errMsg":"closeBLEConnection:ok"}
21:42:41.083  onBLEConnectionStateChange: {"connected":false,"deviceId":"9A48D668-F275-8C7A-6BFE-F14D01B49CAA"}
21:42:41.104  onBLEConnectionStateChange: {"connected":false,"deviceId":"9A48D668-F275-8C7A-6BFE-F14D01B49CAA"}
21:42:41.125  stopBluetoothDiscovery
21:42:41.145  closeBluetoothAdapter
21:42:41.166  onBluetoothAdapterStateChange: {"available":false,"discovering":false}
21:42:41.186  closeBluetoothAdapter success: {"errMsg":"closeBluetoothAdapter:ok"}

IDE运行环境说明

环境 版本
HBuilderX 1.9.9
操作系统 windows7

uni-app运行环境说明

环境 版本
运行端 app
运行端版本号 9.4.18
创建工具 HBuilderX

App运行环境说明

系统 版本
iOS 9.1、12.2、12.1.4、12.1.2
手机型号 -
iPhone5 -
iPhone SE -
iPhone7 Plus -
iPhoneXSMax -
iPhone6s Plus -
iPhoneX -
iPHoneXR -

附件

[QQ:3806994]


更多关于uni-app ios app写入特征值无法正确返回结果的实战教程也可以访问 https://www.itying.com/category-93-b0.html

34 回复

又是石沉大海

更多关于uni-app ios app写入特征值无法正确返回结果的实战教程也可以访问 https://www.itying.com/category-93-b0.html


每次写入完成都启动notifyBLECharacteristicValueChange监听 试试

试过,写完后再调用notifyBLECharacteristicValueChange,onBLECharacteristicValueChange会响应,但返回结果仍然是空,但在xcode里则写入完成后能监听到返回结果

回复 XTiger: 在xcdoe里是说你自己对原生插件吗?

回复 CLP: 用xcode打包的时候真机运行

回复 XTiger: 就是说你是离线用xcode打包的时候,能监听到要的结果;HBuilderX运行的时候不行是吗

回复 CLP: 是的,打好包在手机上运行也不行

回复 XTiger: 什么叫打好包? 是离线打包还是云打包?

回复 CLP: 云打包

是xcode调试的时候可以还是Xcode打包的时候可以,什么情况下不行?是HBuilderX调试的时候不行?

你描述的细节,说不通啊,云打包和xcode离线打包,在蓝牙上没什么区别的,为什么会云打包不行,离线打包可以了

xcode调试的时候可以,离线打包好的我还没试,正在准备试一下,HBuilderX调试和云打包的都是不行的

之前是用的1.9.4的SDK,刚换成2.0.0的SDK试了下,xcode调试也没有返回结果了

openBluetooth

openBluetoothAdapter open adapter success: {“errMsg”:“openBluetoothAdapter:ok”} startDiscovery startDevicesDiscovery startBluetoothDevicesDiscovery success:{“errMsg”:“startBluetoothDevicesDiscovery:ok”} onBluetoothAdapterStateChange: {“available”:true,“discovering”:false} startDiscovery startDevicesDiscovery startBluetoothDevicesDiscovery success:{“errMsg”:“startBluetoothDevicesDiscovery:ok”} onBluetoothDeviceFound: {“devices”:[{“RSSI”:-80,“advertisServiceUUIDs”:[“6E400001-B5A3-F393-E0A9-C0BD13F2AB4E”],“deviceId”:“A80ABA07-373A-4EDF-19B2-925085697685”,“localName”:“000-101”,“name”:“000-101”}]} stopBluetoothDiscovery start connect stop Discovery success: {“errMsg”:“stopBluetoothDevicesDiscovery:ok”} onBluetoothAdapterStateChange: {“available”:true,“discovering”:false} onBLEConnectionStateChange: {“connected”:true,“deviceId”:“A80ABA07-373A-4EDF-19B2-925085697685”} create connection success: {“errMsg”:“createBLEConnection:ok”} startCharacteristicsNotify set notify success: {“errMsg”:“notifyBLECharacteristicValueChange:ok”} onBLECharacteristicValueChange:d00ba53030a73030aa3030 writeCharacteristics:d016303461333136346435306164a53731343334 write characteristics success: {“errMsg”:“writeBLECharacteristicValue:ok”} writeCharacteristics:30a7 onBLECharacteristicValueChange: write characteristics success: {“errMsg”:“writeBLECharacteristicValue:ok”} onBLECharacteristicValueChange: success

如果每次notifyBLECharacteristicValueChange都订阅再监听, 或者readBLECharacteristicValue读也不行的话,我们排查下

每次都是这样

回复 XTiger: 你的write的 property是啥

回复 CLP: 你说的是Characteristic的属性吗?写是true,读是false

还一个问题,一次写入超20个字节,我的蓝牙设备是等所有结果写入完成后才返回结果的,在安卓上是正常的,将超过20字节的数据分成两次写入,等写入完成后,在onBLECharacteristicValueChange会监听到结果,但在苹果里,每次写入都会响应onBLECharacteristicValueChange,但没有结果,可以看上面的日志

回复 CLP: 蓝牙上有两个Characteristic,一个只能写不能读,用来接收写入数据,另一个只能读,用来监听反馈结果

回复 XTiger:把2个特征值完成的属性发一下,我试的特征值write为true时,监听的时候是有返回值的,如果没有任何信息返回应该是写成功了,但是返回的数据就是空,所以js层看到的现象就是没有返回结果,实际在原生层是空值即 value=nil

回复 CLP: 第一个Characteristic: Properties: Notify,这个用于监听返回结果,uni.notifyBLECharacteristicValueChange的时候用的是这个 第二个Characteristic:Properties: Write, Write no response,这个用于写入

写入是成功的,蓝牙设备是有反应的,只是监听不到结果

回复 XTiger: 蓝牙设备是有反应的,这句话是什么意思,有什么反应

Characteristic:Properties: Write, Write no response 这个写的属性,是HX打印出来的吗?

回复 CLP: 蓝牙上面有指示灯,写入成功灯会亮

回复 CLP: Properties: Write, Write no response,这个是用第三方的APP查看的

回复 CLP: 另外,还有这个问题,麻烦也帮忙查查看http://ask.dcloud.net.cn/question/72681 iphone7、ipponeXR两个型号的手机操作完蓝牙后,蓝牙停止广播,怀疑是不是没有正常断开连接。

回复 XTiger: 第一个Characteristic: Properties: Notify 这个属性是true还是false。把HX打印的2个特征值发出来看看

回复 CLP: 第一个Characteristic: Properties: Notify 这个属性是true,第二个Characteristic: Properties: Notify,这个属性是false

回复 CLP: 具体属性看下面的回复的图片,这是用HelloUniApp小程序获取的属性截图

回复 XTiger: 可以的话加下我QQ:3806994,沟通起来方便点

这是一个典型的iOS平台蓝牙通信问题,主要涉及版本兼容性和App Store审核环境差异。以下是关键点分析:

  1. 关于1.9.7版本前后的行为变化:
  • 这是iOS底层蓝牙模块实现的调整,新版本直接触发通知但返回值异常
  • 建议在回调中增加超时处理,当收到空值时延迟100-200ms后主动调用readBLECharacteristicValue
  1. App Store包的特殊表现:
  • 苹果审核环境对蓝牙权限有更严格限制
  • 确保在Info.plist中声明了NSBluetoothAlwaysUsageDescription
  • 上架版本建议增加写入失败后的重试机制(如示例代码中的doIndex)
  1. 临时解决方案:
// 修改writeCharacteristics中的success回调
success: function(e) {
    setTimeout(() => {
        uni.readBLECharacteristicValue({
            deviceId: Param.lockNo.toUpperCase(),
            serviceId: Param.serviceUuid.toUpperCase(),
            characteristicId: Param.characterUuid.toUpperCase()
        });
    }, 200);
}
回到顶部