5

I am trying to use the CoreBluetooth framework and I have created a helper class (btHelper) to make code more maintainable and such.

The problem is that in this helper class, the delegate methods are no longer being called like they were originally when everything was smushed into big class. Yes I have set the delegate method in .h of the helper class and yes I have set the object CBCentralManager delegate to self. I have pretty much done everything the same as when it was all in one class. I believe it has something to do with the main thread but I have very little experience in this.

Specifically, the delegate method that I want called is

-(void)centralManagerDidUpdateState:(CBCentralManager *)central 

Can anyone please tell me what I must do to get delegate calling working as it should in this helper class? Thanks!

The following is the PrimaryViewController class and the btHelper class

btHelper.m

-(void) activateBluetooth
{
self.manager= [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}

- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
  //DELEGATE METHOD THAT NEVER GETS CALLED. SHOULD BE CALLED AS SOON AS self.manager is initiated
   self.isAvailable=FALSE;
   switch (central.state) {
    case CBCentralManagerStatePoweredOff:
        NSLog(@"CoreBluetooth BLE hardware is powered off");
        break;
    case CBCentralManagerStatePoweredOn:
        NSLog(@"CoreBluetooth BLE hardware is powered on and ready");
         self.isAvailable=TRUE;
        break;
    case CBCentralManagerStateResetting:
        NSLog(@"CoreBluetooth BLE hardware is resetting");
        break;
    case CBCentralManagerStateUnauthorized:
        NSLog(@"CoreBluetooth BLE state is unauthorized");
        break;
    case CBCentralManagerStateUnknown:
        NSLog(@"CoreBluetooth BLE state is unknown");
        break;
    case CBCentralManagerStateUnsupported:
        NSLog(@"CoreBluetooth BLE hardware is unsupported on this platform");
        break;
    default:
        break;
}

}

PrimaryViewController.m

-(IBAction)connect
{  
  btHelper *bluetoothManager= [[btHelper alloc]init];
  [bluetoothManager activateBluetooth];

}
Khaled Barazi
  • 8,681
  • 6
  • 42
  • 62
Teddy13
  • 3,824
  • 11
  • 42
  • 69
  • Are you making sure that your bluetooth manager actually does something? E.g. by calling `scanForPeripheralsWithServices`? – TotoroTotoro Dec 18 '13 at 01:05
  • Can you put a breakpoint in your IBAction and see if it is tripping? – Khaled Barazi Dec 18 '13 at 05:33
  • @BlackRider Initiating a CBCentralManager automatically should call the delegate method centralManagerDidUpdateState. This method is crucial in determining the state of Bluetooth (E.g. Whether Bluetooth LTE is supported on the device). From there, and if bluetooth is enabled, one can call a method like scanForPeripheralWithServices – Teddy13 Dec 18 '13 at 08:06
  • @Spectravideo328 What do you mean by tripping? Crashing? I have put breakpoints and everything flows as it should except the delegate method does not get called. Any other suggestions? Thanks – Teddy13 Dec 18 '13 at 08:07

2 Answers2

13

You helper instance is a local variable in the -connect method. So ARC release it (and the CBCentralManager instance) before you can receive delegate methods. Make your helper an instance variable (or property) of PrimaryViewController, and this will fixed your problem.

@interface PrimaryViewController : UIViewController
{
    // BTHelper instead of btHelper, to follow naming convention
    BTHelper *_bluetoothManager;
}
@end

@implementation PrimaryViewController
    -(IBAction)connect
    {
      // FIXME: this don't check if _bluetoothManager is already instantiated
      _bluetoothManager = [[BTHelper alloc] init];
      [_bluetoothManager activateBluetooth];
    }
@end
Emmanuel
  • 2,897
  • 1
  • 14
  • 15
0

Ensure that your btHelper.m adopt the CBCentralManagerDelegate protocol.

@interface btHelper () <CBCentralManagerDelegate> {}

In your case above, most likely you did not get any errors with the method:

- (void)centralManagerDidUpdateState:(CBCentralManager *)central

since as of a few versions ago, the compiler stopped requiring that you declare any private methods (in the interface section of your .m file).

Hope this helps.

Khaled Barazi
  • 8,681
  • 6
  • 42
  • 62
  • Thanks for the response! I did declare the CBCentralManagerDelegate protocol. As for the rest of your answer, I don't see how that helps this situation? It got called when I had everything jumbled up in one class, it has to be called no matter what. Perhaps I am missing your point (most likely the case). If i am, can you please explain some more? Thanks – Teddy13 Dec 18 '13 at 10:18