10

I've paired an IOBluetoothDevice in my Mac/Cocoa app and would like to "unpair" it programmatically. That is, I would like to remove the device from the left pane of the Bluetooth section of System Preferences.

I've seen [IOBluetoothDevice removeFromFavorites], but that just removes the heart icon next to the "Favorite" attribute of the device -- the device is still listed in the left pane.

Is this possible through Cocoa?

Bluetooth Section of System Preferences

In the above picture, I would like to programmatically remove "Apple Mighty Mouse" from the left pane.

Ford
  • 1,485
  • 3
  • 14
  • 20

1 Answers1

10

Paired devices are a part of System Preferences.

You can find the file with the bluetooth preferences in /Library/Preferences, its name is com.apple.Bluetooth.plist.

com.apple.Bluetooth.plist

However, you cannot edit the file directly. You should use SCPreferences class from System Configuration framework.

Note the API for accessing/modifying system preferences is pretty low level.

EDIT: The following code works if run in superuser mode. I am not a Mac OS developer myself but it should be possible to init it with an AuthorizationRef and run it with user mode (the user will confirm access to system configuration).

SCPreferencesRef prefs = SCPreferencesCreate(kCFAllocatorDefault,
                                             CFSTR("Test"),
                                             CFSTR("/Library/Preferences/com.apple.Bluetooth.plist"));

const CFStringRef PAIRED_DEVICES_KEY = CFSTR("PairedDevices");

NSArray *pairedDevices = (__bridge NSArray *) SCPreferencesGetValue(prefs, PAIRED_DEVICES_KEY);

NSLog(@"Paired devices: %@", pairedDevices);

NSString *deviceToRemove = @"e4-32-cb-da-ca-2f";        

NSMutableArray *newPairedDevices = [pairedDevices mutableCopy];
[newPairedDevices removeObject:deviceToRemove];

Boolean valueSet = SCPreferencesSetValue(prefs, PAIRED_DEVICES_KEY, (__bridge CFPropertyListRef) [NSArray arrayWithArray:newPairedDevices]);

NSLog(@"Value set: %@", (valueSet) ? @"YES" : @"NO");

if (!valueSet) {
    NSLog(@"Error: %@", SCCopyLastError());
}

Boolean saved = SCPreferencesCommitChanges(prefs);

if (!saved) {
    NSLog(@"Error: %@", SCCopyLastError());
}

NSLog(@"Saved: %@", (saved) ? @"YES" : @"NO");

CFRelease(prefs);
Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • everything is working great until `SCPreferencesCommitChanges` where I get a `Error Domain=com.apple.SystemConfiguration Code=1002 "Invalid argument" UserInfo={NSDescription=Invalid argument}`. Would you happen to know why this could be going on? Thank you! – Mike JS Choi Apr 19 '19 at 16:11
  • @MikeJSChoi Did you try exactly this code or are you rewriting to Swift? – Sulthan Apr 19 '19 at 16:26
  • I'm trying to rewrite this into Swift! Here's a link to my question https://stackoverflow.com/questions/55764449/modify-scpreferences-persistent-storage-invalid-argument – Mike JS Choi Apr 19 '19 at 16:41