Incorrect BLE Peripheral Name with iOS

后端 未结 4 609
生来不讨喜
生来不讨喜 2021-01-31 19:19

I am writing an iOS app to communicate with a BLE device. The device can change names between connections (not during the BLE connection), but iOS refuses to change the device n

4条回答
  •  花落未央
    2021-01-31 20:02

    Edit - just realized that the second part of the accepted answer above has the same solution :-( I should have read more closely. I will leave this answer here anyway, since it includes RoboVM code.

    I have found a solution to this problem. Adding the GATT Service Changed characteristic didn't work, nor did reading the device name directly from the Device Name characteristic 2A00 since iOS hides the Generic Access service. However, if the peripheral includes its local name in an advertising packet, it is available from the advertisement data dictionary provided on a scan result using the retrieval key CBAdvertisementDataLocalNameKey. I copy this into my BLE device wrapper and use it instead of the name available from the CBPeripheral. Example code in Java for RoboVM is below. The OBJC or Swift equivalent is straightforward.

        @Override
        public void didDiscoverPeripheral(CBCentralManager cbCentralManager, CBPeripheral cbPeripheral, CBAdvertisementData cbAdvertisementData, NSNumber rssi) {
            NSData manufacturerData = cbAdvertisementData.getManufacturerData();
            byte[] data = null;
            if(manufacturerData != null)
                data = manufacturerData.getBytes();
            IosBleDevice bleDevice = new IosBleDevice(cbPeripheral);
            String name = cbAdvertisementData.getLocalName();
            if(name != null && !name.equals(cbPeripheral.getName())) {
                CJLog.logMsg("Set local name to %s (was %s)", name, cbPeripheral.getName());
                bleDevice.setName(name);
            }
            deviceList.put(bleDevice.getAddress(), bleDevice);
            if(!iosBlueMaxService.getSubscriber().isDisposed()) {
                BleScanResult bleScanResult = new IosBleScanResult(bleDevice,
                    cbAdvertisementData.isConnectable(),
                    data);
                bleScanResult.setRssi(rssi.intValue());
                iosBlueMaxService.getSubscriber().onNext(bleScanResult);
            }
        }
    

提交回复
热议问题