BLEデバイスと通信するためのiOSアプリを書いています。デバイスは接続間で名前を変更できますが(BLE接続中ではありません)、iOSはデバイス名の変更を拒否します。
例:名前がSadNameの場合、デバイスに接続できます。切断したり、アプリをシャットダウンしたりして、デバイスの名前をHappyNameに変更します。しかし、デバイスをスキャンすると、iOSは依然として周辺機器名をSadNameとして表示します。
アプリをデバッグして見てみると:
(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
周辺機器名の値はSadNameなので、コードで誤って解釈しているものではないと思います。デバイスをスキャンするときのコードは次のとおりです。
[self.CM scanForPeripheralsWithServices:nil options:0]; // Start scanning
デバイスのUUIDが同じであるため、iOSがキャッシュされたデバイスのリストからプルしているからだと思いますが、それをオーバーライドしたいと思います。
考え?申し訳ありませんが、iOSは初めてです。乾杯-MSchmidtbauer
IOSSDKのCoreBluetoothAPIは、ペリフェラル名を強制的に更新する方法を提供していません。
現在、BLEdeviceのデバイス名が変更されたときにiOSでperipheral.nameを使用することはできません。
Appleは、scanForPeripheralsWithServicesに渡すCBUUIDオブジェクト(1つ以上のサービスUUIDを含む)のリストを指定して、特定のデバイスをスキャンすることをお勧めします。
NSArray *services = @[[CBUUID UUIDWithString: @"2456e1b9-26e2-8f83-e744-f34f01e9d701"] ]; // change to your service UUID!
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
[self.manager scanForPeripheralsWithServices:services options:dictionary];
これにより、didDiscoverPeripheralの呼び出し回数が減ります。 scanForPeripheralsWithServicesにnilを渡すだけではいけません。また、バックグラウンド状態のときにアプリが周辺機器をスキャンできるようにします。
接続が確立される前に利用可能な動的情報をブロードキャストする方法を探している場合は、応答データのアドバタイズまたはスキャンを使用できます。周辺機器は、ローカル名およびメーカー固有のデータというエントリをブロードキャストするように構成できます。このデータは、didDiscoverPeripheralで利用できます。
- (void)centralManager: (CBCentralManager *)central
didDiscoverPeripheral: (CBPeripheral *)peripheral
advertisementData: (NSDictionary *)advertisementData
RSSI: (NSNumber *)RSSI {
NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
NSData *manufacturerData = [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey];
NSLog(@"Local: name: %@", localName);
NSLog(@"Manufact. Data: %@", [manufacturerData description]);
}
ローカル名はNSStringなので、このフィールドのBLEデバイスには印刷可能な文字のみを書き込んでください。 Manufacturer DataはNSDataです、これには任意のバイト値を含めることができるため、ここにバイナリデータを含めることもできます。
使用するBLEデバイスによっては、ローカル名とメーカー固有のデータの長さが制限されます。
BLEデバイスでは、アドバタイズデータとともに128ビットサービスUUIDと8文字のローカル名を送信できます。製造元固有のデータはスキャン応答データに入り、29バイトの長さにすることができます。
Adv./Scan Response Dataを使用することの良い点は、電源を入れ直さなくてもこのBLEデバイスで変更できることです。
提案:
あなたの推測は正しいです。
それはcore-blutetooth
キャッシュ。
通常、BLEデバイスでの名前/サービス/特性の変更は「サポートされていません」。これらのパラメータはすべてキャッシュされています。
これを解決するには2つの方法があります。
または、BLEデバイスのアドバタイズデータを確認してください。 BLEデバイスがデータをアドバタイズするたびに更新される必要があるname
プロパティがある場合があります(アドバタイズデータはキャッシュされません)。
編集-上記の受け入れられた回答の2番目の部分にも同じ解決策があることに気づきました: もっと詳しく読む必要がありました。RoboVMコードが含まれているので、とにかくこの回答をここに残しておきます。
私はこの問題の解決策を見つけました。 iOSがGenericAccessサービスを非表示にしているため、GATT Service Changed特性の追加は機能せず、デバイス名特性2A00からデバイス名を直接読み取ることもできませんでした。ただし、ペリフェラルのローカル名がアドバタイジングパケットに含まれている場合は、---(スキャン結果 で提供されるアドバタイズメントデータディクショナリから取得キーを使用して入手できます CBAdvertisementDataLocalNameKey
=。これをBLEデバイスラッパーにコピーし、CBPeripheralから入手できる名前の代わりに使用します。 RoboVMのJavaのサンプルコードを以下に示します。 OBJCまたはSwiftに相当するものは簡単です。
@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);
}
}
CBPeripheralDelegate
プロトコルにはメソッドが含まれています...
- (void)peripheralDidUpdateName:(CBPeripheral *)peripheral NS_AVAILABLE(NA, 6_0);
...これはこの目的のために作られています。