0

Upon applicationDidEnterBackground or applicationWillResignActive I need to startAdvertising but I get this error:

CoreBluetooth[API MISUSE] <CBPeripheralManager: 0x146a4e30> can only accept this command while in the powered on state.

I use:

- (void)applicationWillResignActive:(UIApplication *)application
{
    _locationManager = [[CLLocationManager alloc] init];
    _locationManager.delegate = self;
    [_locationManager stopRangingBeaconsInRegion:_runningBeacon];
    NSLog(@"stop monitoring");
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"23542266-18D1-4FE4-B4A1-23F8195B9D39"];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:1 minor:1 identifier:@"com.devfright.myRegion"];
    self.beaconPeripheralData = [self.beaconRegion peripheralDataWithMeasuredPower:nil];
    self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil options:nil];
    [self.peripheralManager startAdvertising:self.beaconPeripheralData];

    if ([self.peripheralManager isAdvertising]) {
        NSLog(@"peripeheralManager is advertising");
    }
}

Any help would be appreciated..

pkamb
  • 33,281
  • 23
  • 160
  • 191
snksnk
  • 1,566
  • 4
  • 21
  • 46

2 Answers2

2

If you want to actively send out BT advertisement data from your app, I think your app has to be in the foreground. This is from the Apple Class Reference

[..]Data advertising is done on a “best effort” basis, because space is limited and there may be multiple apps advertising simultaneously. While your app is in the foreground, it can use up to 28 bytes of space in the initial advertisement data for any combination of the supported advertising data keys[..]

While in background, you can only listen to beacons. For that you have to register your app and beacon data to the CLLocationManager

Argent
  • 390
  • 1
  • 3
  • 11
  • Can you think of a way to "bypass" this "limitation" and still be app store approved? – snksnk May 14 '14 at 16:43
  • 1
    From what I read, Apple restricts the CoreLocation framework from advertising in the background. But it seems that it is possible to send BT advertisement data in the background with CoreBluetooth. I don't know if you can get full iBeacon functionality with this approach and I also don't know if Apple will approve this in the AppStore... but it's worth a try. Here is a GitHub project that deals with this problem https://github.com/Instrument/Vicinity/ – Argent May 14 '14 at 16:53
1

To silence this error, wait to call the CBPeripheralManager method startAdvertising: in the delegate method peripheralManagerDidUpdateState:. The key here is to make sure the peripheral state is always equal to CBPeripheralManageStatePoweredOn before performing any CBPeripheralManager methods.

Justin Moser
  • 2,005
  • 3
  • 22
  • 28
  • whilst this is a correct answer for the foreground state, the behaviour for iOS 11in the *background* is: even if the peripheral.state is .poweredOn the advertising cannot be started and the error "API MISUSE: can only accept this command while in the powered on state" is logged. – Lepidopteron Jul 11 '18 at 06:48