Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

macOS CBCentralManager state unsupported

I'm attempting to access bluetooth peripherals on macOS (2017 iMac), however the CBCentralManager never seems to enter the .poweredOn state.

import Cocoa
import CoreBluetooth

class BluetoothManager: NSObject {
  var centralManager: CBCentralManager!
  override init() {
    super.init()
    self.centralManager = CBCentralManager(delegate: self, queue:nil)
    self.checkState()
  }

  func checkState() {
    print("central state: \(self.centralManager?.state.rawValue ?? -1)")
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(2), execute: {
      self.checkState()
    })
  }
}


extension BluetoothManager: CBCentralManagerDelegate {
  func centralManagerDidUpdateState(_ central: CBCentralManager) {
    switch central.state {
    case .poweredOn:
      print("Power on")
    case .unsupported:
      print("Unsupported")
    default:break
    }
  }
}


@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

  var bluetoothManager: BluetoothManager?

  func applicationDidFinishLaunching(_ aNotification: Notification) {
    self.bluetoothManager = BluetoothManager()

  }

  ...

}

This will consistently output Unsupported, with a console warning

[CoreBluetooth] XPC connection invalid

I am aware of the Info.plist key NSBluetoothPeripheralUsageDescription, which I tried, though I believe that is just for iOS devices.

Am I looking in the wrong direction for managing bluetooth on an iMac? Or is my implementation missing something? I feel like I have covered everything required in the Core Bluetooth documentation.

like image 279
comfortablejohn Avatar asked Dec 06 '22 12:12

comfortablejohn


1 Answers

I believe this was due to having the App Sandbox enabled (found in the project Capabilities).

Enabling Bluetooth (under Hardware), and accepting the auto changes to entitlements file resolved the issues.

Also disabling the App Sandbox seems to work, however I'm not knowledgeable enough to know if this is safe to do.

For reference, my entitlements file now looks like this:

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">  
<plist version="1.0">   
<dict>  
    <key>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.device.bluetooth</key>
    <true/>
    <key>com.apple.security.files.user-selected.read-only</key>
    <true/>
</dict> 
</plist>    
like image 166
comfortablejohn Avatar answered Dec 29 '22 03:12

comfortablejohn