Incoherent CBCentralManager state in iOS 11

Hello everyone,


Starting with iOS 11, we're consistently encountering an issue with CBCentralManager where bluetooth antenna seems to be enabled but CBCentralManager actually reports .poweredOff.


Steps to reproduce

  1. Bluetooth is enabled in both Settings panel and in Control Center. Launching a dummy app that instanciates a CBCentralManager describes it's state as .poweredOn. (let's call this working state)
  2. Swipe Control Center and disable Bluetooth.
  3. Without leaving Control Center enable Airplane Mode (this fades all wifi, 3G and Bluetooth icons).
  4. Again, without leaving Control Center, disable Airplane Mode (this should automatically enable at least Bluetooth).
  5. Open the same dummy app as in step 1.


Expected result

CBCentralManager should report .poweredOn state.


Observed result

CBCentralManager state is .poweredOff.


Additional observations

This issue has been confirmed on both iPhone 7 running iOS 11.1.1 and iPhone SE running iOS 11.0.3. The behaviour has also been confirmed with other apps like LightBlue.


In another dummy app (let's call it dummyB) that permanently holds a reference to a CBCentralManager instance, if steps 3 and 4 are executed while the app is running, the existing CBCentralManager instance's centralManagerDidUpdateState: callback will report .poweredOff, as stated above. Now, if we disable-enable bluetooth in the system-wide Settings panel, upon returning to dummyB, centralManagerDidUpdateState: will report .poweredOn, but any new fresh instance of CBCentralManager will report .poweredOff state.


Known workarounds

Apparently, the only way to restore a sane Bluetooth stack state is to disable-enable the option in the Control Center (assuming it's already enabled in the Settings panel). From the on, references to CBCentralManager instances both in background running apps and fresh instances report .poweredOn state and connections can successfully be established with peripherals.

Replies

Do you still see the problem? Do you have the sample code/app?

Still happening in 11.3 beta 5. I reported this to Apple 4 months ago as radar # 35580104 (marked as duplicate of 35403769).


Another way to reproduce the bug that doesn't require going into airplane mode:

  1. Disable Bluetooth connections from Control Center.
  2. Disable Bluetooth from the Settings app.
  3. Enable Bluetooth from either the Settings app or Control Center.


Doesn't take much code to demonstrate the problem. The app just needs to initialize a CBCentralManager instance and check what the central state is reported to be.


For example, create a single view app and paste this into ViewController.swift:


import UIKit
import CoreBluetooth

class ViewController: UIViewController, CBCentralManagerDelegate {

    var centralManager: CBCentralManager!

    override func viewDidLoad() {
        super.viewDidLoad()
        centralManager = CBCentralManager(delegate: self, queue: nil)
    }

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        NSLog("centralManagerDidUpdateState: \(central.state.description)")
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        NSLog("Current state: \(centralManager.state.description)")
    }
}

extension CBManagerState: CustomStringConvertible {
    public var description: String {
        switch self {
        case .unknown: return ".unknown"
        case .resetting: return ".resetting"
        case .unsupported: return ".unsupported"
        case .unauthorized: return ".unauthorized"
        case .poweredOff: return ".poweredOff"
        case .poweredOn: return ".poweredOn"
        }
    }
}

Same here. I reported it as a bug too (#39934252) and was marked as a duplicate of #35403769. I did not see this post before submitting the bug.

I tested it in:

0. iPhone 5S - iOS 11.3.1

1. iPhone 6 - iOS 11.3.1

2. iPhone 6s+ - iOS 11.2.2

3. iPhone 7 - iOS 11.3

4. iPhone 8 - iOS 11.2.6

5. iPhone X - iOS 11.3


I hope it will be resolved soon becouse it heavily impacts the behaviour of the current framework I am working on.


Cheers

I met the same problem. https://forums.developer.apple.com/message/311251


I think the reason is that turn off Bluetooth at the control center,


then turn off Bluetooth and turn on Bluetooth at system settings.


At this point, the Bluetooth status in the control center and system settings is turned on,


(the Bluetooth button state of the control center is updated by system settings. Maybe it's a UI bug)


but actually it was closed once in the control center,


so in "centralManagerDidUpdateState", state is poweroff, Bluetooth doesn't work.

As an update, let be known that as of iOS 11.3.1 this issue doesn't seem to happen anymore, at least in an iPhone 7.