Mac OS X 10.10 Reorder preferred networks

838 Views Asked by At

What is the best way to programmatically change the order of "preferred" networks in OS X? Objective-C preferred...

I can use CoreWLAN to gather the list, and even add to it, but as far as re-ordering I am at a loss. I can create a copy of the preference file, edit it and change the order of precedence, and then use a bash script to write over the existing configuration, but that seems a but messy.

I am aware of the networksetup -addpreferredwirelessnetworkatindex command, but it does not work correctly in 10.10 (works fine for 10.9 systems) - it adds but does not set order properly.

SystemConfiguration framework? Something else?

Thanks!

1

There are 1 best solutions below

1
On BEST ANSWER

I was looking for a way to accomplish this after transitioning a user from an open wireless network to a WPA2E network using EAP-TTLS. Since the user connects to the open network first, it remains higher in the Preferred Networks list.

Here is what I came up with:

CWInterface *interface = [CWInterface interfaceWithName:[
    [CWInterface interfaceNames] anyObject]
];
CWMutableConfiguration *config = [CWMutableConfiguration
    configurationWithConfiguration:interface.configuration
];
NSMutableArray *networks = [NSMutableArray arrayWithArray:
    [config.networkProfiles array]
];

//Remove URI_Open (if present) and
//move URI_Secure (if present) to index 0
for (CWNetworkProfile *profile in [networks copy]) {
    if ([[profile ssid] isEqualToString:@"URI_Secure"]) {
        [networks removeObject:profile];
    } else if ([[profile ssid] isEqualToString:@"URI_Open"]) {
        CWNetworkProfile *tmp = profile;
        [networks removeObject:tmp];
        [networks insertObject:tmp atIndex:0];
    }
}

config.networkProfiles = [NSOrderedSet orderedSetWithArray:networks];

SFAuthorization *auth = [SFAuthorization authorization];
BOOL authResult = [auth obtainWithRight:"system.preferences"
    flags:(
        kAuthorizationFlagExtendRights |
        kAuthorizationFlagInteractionAllowed |
        kAuthorizationFlagPreAuthorize
     ) error:nil
];

NSError *error = nil;
[interface commitConfiguration:config authorization:auth error:&error];

Some notes/disclaimers:

  • I do not use OS X regularly. I have one test Mac in my office. It has 10.7.5 installed.
  • This is the first thing I have ever written in Objective-C. It is the result of a single afternoon; as such it is probably broken and ugly. YMMV.
  • Question specified 10.10. I used interfaceWithName and interfaceNames, which are deprecated in 10.10. I am not sure what the proper replacement is, but I suspect CWWifiClient.
  • My approach was based loosely on this ruby program.
  • I removed error handling for brevity.
  • I did look into using networksetup or removing the open network right in the .mobileconfig, but neither seemed to work quite right.
  • Since I just pull the network profile list out into a mutable array, this is easily adaptable to any arbitrary sorting etc.