I am building an application where two iOS devices both transmit and scan (peripheral and central) for each other. Due to Apple's implementation, when the app is backgrounded, all identifiable information is removed from the advertising packet, meaning I need to connect to the discovered peripherals to find out who and what they are if they are transmitting in the background.
All I really need to do is identify the peripheral. (Connect and disconnect). Currently, the only way I can find to do this is to set a static characteristic attached to a common service that allows each device to uniquely identify itself, even when backgrounded. This value will not change or get updated. If I could simply look at peripheral.UUID after connecting, this would do the trick. But I can't anymore with iOS8. So, I create a characteristic to contain the unique identifier.
(Not sure if this is the best way, but its the only way I can think of.)
Everything is working great (discovering characteristic) but I am unable to retrieve anything other than nil for the characteristic, even though I have specifically set it when I started transmitting.
Here is my (Peripheral code):
-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
// Opt out from any other state
if (peripheral.state != CBPeripheralManagerStatePoweredOn) {
return;
}
NSLog(@"BT Transmitter Powered On");
NSString* uniqueString = @“foobar";
NSData* characteristicValue = [uniqueString dataUsingEncoding:NSUTF8StringEncoding];
self.transferCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:@"08590F7E-DB05-467E-8757-72F6FAEB13D4"]
properties:CBCharacteristicPropertyRead
value:characteristicValue
permissions:CBAttributePermissionsReadable];
CBMutableService *transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:@"E20A39F4-73F5-4BC4-A12F-17D1AD07A961"] primary:YES];
transferService.characteristics = @[self.transferCharacteristic];
[self.peripheralManager addService:transferService];
[self.peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey: @[[CBUUID UUIDWithString:@"E20A39F4-73F5-4BC4-A12F-17D1AD07A961"]] }];
}
And here is my Central Code:
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
if (error) {
NSLog(@"Error discovering characteristics: %@", [error localizedDescription]);
return;
}
for (CBCharacteristic *characteristic in service.characteristics) {
// print out value of discovered characteristic
NSLog (@"Characteristic discovered: %@", characteristic); // this outputs all all the properties of the characteristic, including a value of "null".
NSString *value = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
NSLog(@"Value: %@",value); // this prints out nothing
}
}
What am I doing wrong? I would expect to see the value of the characteristic as "foobar" when transformed back into an NSString. Instead it is null.