iOS CoreBluetooth : centralManager:didConnectPeripheral / didFailToConnectPeripheral: not getting called - ios

I'm pulling my hair out of this problems. I'm trying to connect to BLE devices, can't see what I've done wrong in my code below.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_cm = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
+ (NSString*)UUIDString:(CFUUIDRef)uuid {
CFStringRef string = CFUUIDCreateString(NULL, uuid);
return (__bridge_transfer NSString*)string;
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
if (central.state == CBCentralManagerStatePoweredOn) {
[self scanForPeripherals];
}
}
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {
// NSLog(#"Received peripheral : \n%#", peripheral);
// NSLog(#"Adv data : %#", advertisementData);
[peripheral setDelegate:self];
[central connectPeripheral:peripheral options:nil];
[peripheral readRSSI];
}
- (int)scanForPeripherals {
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], CBCentralManagerScanOptionAllowDuplicatesKey,
nil];
[_cm scanForPeripheralsWithServices:nil options:options];
return 0;
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(#"didConnectPeripheral");
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(#"didDisconnectPeripheral");
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(#"failed to connect");
}
- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error {
NSLog(#"didReadRSSI");
}
These devices are not my own. I don't know its proximity UUID, but as far as I know, It won't be needed in connecting via CoreBluetooth right?
All of the devices are discovered in didDiscoverPeripheral:, in the selector I tried to connect them. But there's nothing comes after that.
Am I to expect a dialog with Pairing Password Request when I called to didDiscoverPeripheral:?
If so I don't see any dialog, why is that?
From apple documents, It clearly stated that after trying to connect to a device you should get a called to either didConnectPeripheral or didFailToConnectPeripher but I got none.
Any thoughts? I've been trying for almost a week now.
Appreciate every helps, thanks.

If you don't somehow retain the peripheral object that is delivered to didDiscoverPeripheral then it is released once this delegate method exits and you won't get a connection.
I suggest adding a property to track discovered peripherals
#property (strong,nonatomic) NSMutableArray *peripherals;
initialise this in viewDidLoad or init
self.peripherals=[NSMutableArray new];
And then add the peripheral to it in didDiscoverPeripheral
-(void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(#"Discovered peripheral %#",peripheral.identifier.UUIDString);
[self.peripherals addObject:peripheral];
[central connectPeripheral:peripheral options:nil];
}

var peripherals = [CBPeripheral]()
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
peripherals.append(peripheral)
bleManager.connectPeripheral(peripheral, options: nil)
}
This is the Swift version.

Related

CoreBluetooth , BLE : couldn't discover peripheral

I have a BLE device (obd2 dongle) that I want to connect to. I can pair with it through "settings" but I can't discover it via didDiscoverPeripheral delegate method , any help ?
- (void)viewDidLoad {
[super viewDidLoad];
_centralManager =[[CBCentralManager alloc]initWithDelegate:self queue:nil];
[self scan];
}
-(void)scan {
NSDictionary *options1 =#{ CBCentralManagerScanOptionAllowDuplicatesKey : #YES };
[_centralManager scanForPeripheralsWithServices:nil options:options1];
}
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
if (central.state == CBCentralManagerStatePoweredOn) {
[self scan];
}
}
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI {
[peripheral readRSSI];
[central connectPeripheral:peripheral options:nil];
}
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
CBPeripheral *peripheral1 =peripheral;
NSLog(#"peripheral1 name = %#",peripheral1.name); peripheral.delegate=self;
[peripheral discoverServices:nil];
}

didDiscoverPeripheral never called

I have two devices (ipad 3 and iphone 4s), and was trying to find a way to recognize one of the two devices (For future exchange information between them), for that, I'm with active Bluetooth devices in 2, and using the following code:
- (void)viewDidLoad {
[super viewDidLoad];
CBUUID *otherDevice = [CBUUID UUIDWithString:#"180A"];
NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
self.mgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
[self.mgr scanForPeripheralsWithServices:[NSArray arrayWithObject:otherDevice] options:scanOptions];
}
#pragma mark - delegates
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
NSLog(#"I found new devices -> %#",[NSString stringWithFormat:#"%#",[advertisementData description]]);
}
-(void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals{
NSLog(#"This is it!");
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
NSString *messtoshow;
switch (central.state) {
case CBCentralManagerStatePoweredOn:
{
messtoshow=[NSString stringWithFormat:#"Bluetooth is currently powered on and available to use."];
[self.mgr scanForPeripheralsWithServices:nil options:nil];
break;
}
}
NSLog(#"%#",messtoshow);
}
The problem with this code is that I am getting the message on the console that bluetooth is active, but the method 'didDiscoverPeripheral:' not being called, why this is happening? (since the Bluetooth on both devices are active)?

Could you advise to discover any bluetooth device on iOS?

I try to make program to detect uncertain Bluetooth device at iOS.
The device scanning work well but it could not detect any device. However in the basic option in Ipad, the bluetooth devices were detected well. Bellow show the my code. Please advise to fix some problem.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//CB setup
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
// You should test all scenarios
if (central.state != CBCentralManagerStatePoweredOn) {
return;
}
if (central.state == CBCentralManagerStatePoweredOn) {
_scan_state = 1;
}
[self deviceScan];
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
NSLog(#"dicovered: %#", peripheral.name);
if(![self.BTNames containsObject:peripheral]){
[self.BTNames addObject:peripheral];
}
_num_cell = self.BTNames.count;
[self.BTList reloadData];
}
- (void) deviceScan{
if(_scan_state){
/* [_centralManager scanForPeripheralsWithServices:nil options:#{ CBCentralManagerScanOptionAllowDuplicatesKey : #NO }];*/
[_centralManager scanForPeripheralsWithServices:nil options:nil];
NSLog(#"Scan Starting");
}
}

In CBCentralManager delegate method didDiscoverPeripheral: never called

I initialize the CBCenteralManager in viewdidload on main queue. First time update state method is called and start scanning for bluetooth devices but didDiscoverPeripheral: delegate method never get called.
Code is :
- (void)viewDidLoad
{
[super viewDidLoad];
self.CM = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
}
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
if (central.state == CBCentralManagerStatePoweredOn) {
[self.CM scanForPeripheralsWithServices:nil options:nil];
}
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral(CBPeripheral*)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
}
-(void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals{
}
-(void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals{
}
-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
}
-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
}
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
}

Bluetooth low energy iOS how get service name

I have one Bluetooth device with some service. I'm able to connect my app with this device, and I'm able to see all services of my BT device, but I would like to see what is the name of the various services, for example:
Device Information
UUID : 0x180A
I think it is possible because some universal app allow you to view it.
Follow the Apple tutorial, it is very clear there :
Starting with:
#interface ViewController () <CBCentralManagerDelegate, CBPeripheralDelegate>
//centralManager:willRestoreState:
#property (nonatomic,strong) CBPeripheral *connectingPeripheral;
#end
#implementation ViewController
{
CBCentralManager *centralManager;
}
Then:
- (void)viewDidLoad
{
[super viewDidLoad];
//Starting Up a Central Manager
centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil
options: nil];
}
initWithDelegate: queue: options: calls through CBCentralManagerDelegate:
- (void) centralManagerDidUpdateState:(CBCentralManager *)central
{
[centralManager scanForPeripheralsWithServices:nil //Services
options:nil];
}
scanForPeripheralsWithServices: options: calls through CBCentralManagerDelegate:
- (void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
self.connectingPeripheral = peripheral;
//You should connect to your BLE Device with:
[centralManager connectPeripheral:self.connectingPeripheral
options: nil]
}
The response of this call is through the delegate connectPeripheral: options:
Then:
- (void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
//(...)
[peripheral discoverServices:nil]; // Service
}
discoverServices: calls peripheral: didDiscoverServices: from CBPeripheralDelegate
- (void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
for (CBService *service in peripheral.services)
{
NSLog(#"Discovered service %#", service);
NSLog(#"Discovered service %#", service.UUID);
}
}
There you have what you want!
It is important to know the properties of a CBService:
Identifying a Service
UUID property
peripheral property
isPrimary property
Accessing Service Data
characteristics property
includedServices property

Resources