Peripheral name doesn't comply to NameKey

4.9k views Asked by At

I have an app that simulates heart rate monitor peripheral (The peripheral app). I also have an app that receives the data and present it (The central app).

The central app decided to connect to the discovered peripheral based on its name.

The problem is that both app work perfectly good, except that the name is always "iPhone".

The advertising is done this way:

- (IBAction)switchChanged:(id)sender
{
    if (self.advertisingSwitch.on) {
        NSDictionary *advData =
        @{CBAdvertisementDataLocalNameKey:@"Custom Name",
          CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:@"180D"]]};
       [self.peripheralManager startAdvertising:advData];
        NSLog(@"Advertising");
    }

    else {
        [self.peripheralManager stopAdvertising];
        [[self timerInterval] invalidate];
        NSLog(@"Stopped advertising");       
    }      
}

But on the central side, inside

- (void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)aPeripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

The name property never changed.

Is there anything that should be done?

6

There are 6 answers

0
allprog On BEST ANSWER

Unfortunately, there is no other way to set the peripheral name. iPhone will always have the name: iPhone.

The advertisement is probably correctly seen on the central side. You may check by NSLogging the advertisementData. However, if you rely on the peripheral.name property, then that will either be empty (if you connect first) or contain the "iPhone" string.

0
Taryn On

In most such applications instead of identifying the peripheral by name, the client app should be identifying it by a service ID, and the server (peripheral), should be providing a either a standard service ID, as defined at bluetooth.org, or a proprietary service ID/name.

1
Dan1one On

I remember it is used to happen to me and I figured it was something to do with the way Core Bluetooth handles caching and service discovery. What Happened to me was that at first I received a default name like iPhone, iPad or nothing at all. But then after discovering services or trying to establish a connection the key magically changes to the value I had set on the other end.

Moreover, it seems it only happens the first time, afterwards, even between launches and subsequent runs of the app Core Bluetooth will try its best to return those values to you on the advertisement stage even on first discovery, but those might as well be outdated values.

my current implementation looks as follows:

NSString * baconName = [[UIDevice currentDevice] name];
NSDictionary *advertisementData = @{CBAdvertisementDataServiceUUIDsKey:@[[CBUUIDUUIDWithString:BACON_SERVICE_UUID]],
CBAdvertisementDataLocalNameKey:baconName};

And It just works for me, iPhones love Bacon, everybody does ;).

Hence, the best way to ensure you get any data you want, is to create another characteristic to transmit your flag and do constant discoveries of services and characteristics for Peripherals you are discovering, and accordingly minimise the discovery of existing or cached peripherals by caching or keeping a reference to them, CB is supposed to do this for ya, and they do their best effort but only you know the business logic of your app and what is important to you. I am overly paranoid and keep references to the discovered peripherals I am interested all the time. That is just me: it ensures I have the right information, and that I minimise scanning and constant re discovery of services and characteristics.

I Hope this helps.

0
user3221820 On

CBAdvertisementDataLocalNameKey only change kCBAdvDataLocalName in advertisementData. When you nslog advertisementData, you will see some data like this:

{
    kCBAdvDataIsConnectable = 1;
    kCBAdvDataLocalName = Custom Name;
    kCBAdvDataServiceUUIDs =     (
        "FB694B90-F49E-4597-8306-171BBA78F846"
    );
}
1
Mike On

What I have observed with CBPeripheral.name is that the device will, in fact, set the name to the name you select with CBAdvertisementDataLocalNameKey. This name is not persistent, though. If you disconnect the master and reconnect,the name will generally have been switched to "iPhone". If the peripheral disconnects due to an error, I have seen it reconnect with the correct peripheral name, but a new UUID.

There may be other situations where the name also switches to iPhone.

This appears to be a bug in iOS. I'm looking for confirmation before reporting it.

0
Dmitry Soloviov On

I have the same problem. I argee with Mike, this really seems like bug in IOS. If you discover your peripheral with TI multitool (for example) first, then your device will be discovered as you setuped in CBAdvertisementDataLocalNameKey.

to Dan1one: you should use [[UIDevice currentDevice] model], not name, to get the string same to default.