What causes CBCentralManagerStateUnknown in iOS?

后端 未结 6 2707
灰色年华
灰色年华 2021-02-20 06:15

Why do I get CBCentralManagerStateUnknown on an iPad 2 when using this simple code?

- (BOOL)viewDidLoad {

    bluetoothManager = [[CBCentralManager         


        
相关标签:
6条回答
  • 2021-02-20 06:51

    CBCentralManagerStateUnknown simply means iOS has started the BLE process, but has not completed initialization. Give it a moment, and the state will change.

    In general, you will "give it a moment" by detecting a state chang in a CBCentralManagerDelegate delegate handler rather than looking at it right after the initialization call. You will implement

    - (void) centralManagerDidUpdateState: (CBCentralManager *) central;
    

    There are some good examples that show this, such as Apple's heart rate monitor.

    0 讨论(0)
  • 2021-02-20 06:51

    If a central's state goes to CBCentralManagerStateUnsupported (while Bluetooth Low Energy is supported by the device) it most likely means the app has done something bad with CoreBluetooth.

    Check the iOS Bluetooth Diagnostic Logging logs.

    For example, if you do this...

    _cm1 = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{ CBCentralManagerOptionRestoreIdentifierKey: @"not_unique" }]; _cm2 = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{ CBCentralManagerOptionRestoreIdentifierKey: @"not_unique" }];

    ... the second central's state will go to CBCentralManagerStateUnsupported.

    0 讨论(0)
  • 2021-02-20 06:55

    I know why delegate is never called. Because the object is deleted from memory. Just make a strong property

    @property (strong, nonatomic) DiscoverBluetoothDevices *btDevices;

    And in init

    @implementation DiscoverBluetoothDevices
    - (id) init
    {
        self = [super init];
        if(self) {
            centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
            [centralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey: @YES}];
    
        }
        return self;
    }
    

    And now delegate is called properly.

    0 讨论(0)
  • 2021-02-20 07:01

    In my case I did use AppDelegate as delegate for

    CBCentralManagerDelegate
    

    and indirectional for

     AVCaptureMetadataOutputObjectsDelegate.
    

    in one time.

    1) Take care about threads. Use

    dispatch_get_main_queue() 
    

    or

    [NSThread mainThread]
    

    for work with BLE.

    2) Take care about using this 2 delegates on 1 object. Because hardware is NOT thead and context save

    0 讨论(0)
  • 2021-02-20 07:07

    You need to both retain the CBCentralManager instance (put it in an ivar or private property) and wait for the state change delegate to be called. (The state is always "unknown" if you check it immediately after instantiating the manager. The real state will appear momentarily in the delegate method.)

    0 讨论(0)
  • 2021-02-20 07:15

    The actual answer (old question I know); start a scan for peripherals, this will start BT LE up and your delegates will get called back. My Delegates and state info did not change until I did this.

    a. Setup your cbcentralmanager as below b. Have the -central* delegates in your code and in your .h file c. NSLog or have a label on screen update with new status. And... Success.

    cManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    
    [cManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey: @YES}];
    
    0 讨论(0)
提交回复
热议问题