CoreBluetooth: Refreshing local name of an already discovered Peripheral
Asked Answered
S

2

10

I successfully discover a Peripheral and retrieve its local name:

[advertisementData objectForKey:CBAdvertisementDataLocalNameKey]

But if the Peripheral stops and restarts advertising with a different local name, the Client doesn't recognise the change. I guess

- (void)peripheralDidUpdateName:(CBPeripheral *)peripheral

only works if the two devices are paired. Is there a way to get an update without pairing?

Stig answered 1/11, 2012 at 15:18 Comment(0)
S
5

Apple's bug. Still present in iOS 6.1. Here is the trick how to reset CB cache:

  1. BackUP device to iCloud.
  2. Reset network settings.
  3. Delete your app and install it back via Xode
  4. At this point, your peripheral will appear with the new name.
  5. Restore your network settings manually or restore from iCloud.

Sorry.

Schumann answered 4/2, 2013 at 5:3 Comment(5)
oh boy oh boy.. the CoreBluetooth API is so flakey.. (null UUIDs, stupid cache issues.. arrrr)Unique
Sadly, still present in iOS8 :(Tern
This is getting ridiculous and really frustrating.Woolfolk
This answer https://mcmap.net/q/1167982/-corebluetooth-device-name-change suggests Apple doesn't believe it's a bug.Hemmer
Still present in IOS 12.Maiduguri
B
0

You can use KVO on the name property which will work even when not connected, at least this is the case in OS X 10.10. I just use this to call the -peripheralDidUpdateName: method myself, and de-dupe calls by tracking the name string.

self.name = self.peripheral.name;
[self.peripheral addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:NULL];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if([keyPath isEqualToString:@"name"]) {
        [self peripheralDidUpdateName:self.peripheral];
        return;
    }
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}


- (void)peripheralDidUpdateName:(CBPeripheral *)peripheral {
    if([peripheral.name isEqualToString:self.name]) return;
    if([self.delegate respondsToSelector:@selector(peripheralDidUpdateName:)]) {
        [self.delegate peripheralDidUpdateName:self];
    }
}
Boxhaul answered 4/11, 2014 at 0:22 Comment(1)
Hi Nick, I know this is old but the topic problem still exists and I would like to try your solution out. I have started a new topic about how to implement your code, perhaps you could help me out there: https://mcmap.net/q/1167983/-inserting-objective-c-sample-code-sections-into-a-working-xcode-objective-c-ios-project/1984167Chickenhearted

© 2022 - 2024 — McMap. All rights reserved.