Get IOBluetoothDevice * from CBPeripheral * (Mac OS X)

785 Views Asked by At

I am wondering if there is a way i can get an IOBluetoothDevice * object from a CBPeripheral * object because I am making an advanced bluetooth controller framework (Its going to be based on IOBluetooth) and Im using it so scan for Bluetooth Classic and Bluetooth Low Energy devices. Here are some of the problems:

  1. IOBluetooth does allow you to search for both networks but for some reason its not showing up all of the Bluetooth Low Energy Devices that CoreBluetooth is.

  2. If I use CoreBluetooth to search for Bluetooth Low Energy Devices I won't be able to get the address which I require for later use.

So is there any way i can get an IOBluetoothDevice object from a CBPeripheral?

thanks :D

2

There are 2 best solutions below

0
MacMan On BEST ANSWER

I found out that I can search through /Library/Preferences/com.apple.bluetooth.plist > CoreBluetoothCache which just happens to contain the UUID and in its dictionary DeviceAddress = the address ;).

so I can get the UUID of a CBPeripheral by using the method

NSString *uuid = [[<*CBPeripheral*> identifier] UUIDString]; 

and then looking it up in the property list

NSDicionary *btdict = [NSDictionary dictionaryWithContentsOfFile:@"/Library/Preferences/com.apple.bluetooth.plist"];
NSDictionary *bleDevices = [btDict objectForKey:@"CoreBluetoothCache"];
NSString *address = [[bleDevices objectForKey:uuid] objectForKey:@"DeviceAddress"];

Then create a new IOBluetoothDevice with that address:

IOBluetoothDevice *device = [IOBluetoothDevice deviceWithAddressString:address];

Its as easy as that :D

0
inexcitus On

Swift 5.3 solution:

fileprivate func getDeviceAddress(for cbPeripheral: CBPeripheral) -> String?
{
    if let userDefaults = UserDefaults(suiteName: "/Library/Preferences/com.apple.Bluetooth")
   {
        if  let coreBluetoothCache = userDefaults.object(forKey: "CoreBluetoothCache") as? [String : Any]
        {
            if let deviceData = coreBluetoothCache[cbPeripheral.identifier.uuidString] as? [String : Any]
            {
                return deviceData["DeviceAddress"] as? String
            }
        }
    }
        
    return nil
}

Usage:

if let deviceAddress = self.getDeviceAddress(for: peripheral)
{
    if let bluetoothDevice = IOBluetoothDevice(addressString: deviceAddress)
    {
        // Do your stuff
    }
}