iOS/Objective-C: BLE in Peripheral mode doesn't work iOS/Objective-C: BLE in Peripheral mode doesn't work objective-c objective-c

iOS/Objective-C: BLE in Peripheral mode doesn't work


You are probably adding the service transferService too early to the peripheral manager and you are also probably starting the advertisement too early.

You have to wait until peripheralManagerDidUpdateState reports that your peripheral manager's state has reached CBPeripheralManagerStatePoweredOn.

This said, you can either move the code from RCT_EXPORT_METHOD(start:(NSDictionary *)options) into your empty peripheralManagerDidUpdateState implementation.

Alternatively, if you only want to add services to your peripheralManager and then start advertising when somebody has called your start method (looks like you're creating a React Native binding?), make sure that self.peripheralManager.state is CBPeripheralManagerStatePoweredOn within your start method. This however requires the caller of start (your React Native JS code) to not call this method too early.

RCT_EXPORT_METHOD(start:(NSDictionary *)options){  NSLog(@"Start?");  if (self.peripheralManager.state != CBPeripheralManagerStatePoweredOn) {      NSLog(@"Peripheral is not powered on");      return;  }  if (self.centralManager.state != CBCentralManagerStatePoweredOn) {      NSLog(@"Central is not powered on");      return;  }  NSLog(@"OK, peripheral and central are both powered on");  [self.centralManager scanForPeripheralsWithServices:nil options:nil];  self.transferCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:@"EB6727C4-F184-497A-A656-76B0CDAC633A"] properties:CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable];  CBMutableService *transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:@"EB6727C4-F184-497A-A656-76B0CDAC633A"] primary:YES];  transferService.characteristics = @[self.transferCharacteristic];  [self.peripheralManager addService:transferService];  [self.peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:@"FB694B90-F49E-4597-8306-171BBA78F846"]] }];  NSLog(@"Started");}

Similarly you can only start scanning for peripherals with your centralManager if it has the "powered on" state.


Apparently, there is no way to programmatically turn the Bluetooth on in iOS as well as the pairing is not possible programmatically right now.

However, we can intimate user to turn on the Bluetooth via alert as below in RCT_EXPORT_METHOD(start:(NSDictionary *)options) method.

if(peripheralManager.state < CBPeripheralManagerStatePoweredOn){{     //Show alert to user to turn on the Bluetooth and it will go to        peripheralManagerDidUpdateState when user turn it on.}else{     //You can continue setting up the data.}