I'd like to subscribe to WiFi network changes in my Cocoa application, but I haven't been able to find an appropriate event to subscribe to.
Is there an NSNotificationCenter Notification for WiFi network changes?
Not to my knowledge. I would use CoreWLAN to get a list of all WiFi interfaces on the system, and then monitor their status using the SystemConfiguration framework.
Here's a command-line example (error checking niceties elided, ARC required):
#import <Foundation/Foundation.h>
#import <CoreWLAN/CoreWLAN.h>
#import <SystemConfiguration/SystemConfiguration.h>
void wifi_network_changed(SCDynamicStoreRef store, CFArrayRef changedKeys, void *ctx)
{
[(__bridge NSArray *)changedKeys enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
{
/* Extract the interface name from the changed key */
NSString *ifName = [key componentsSeparatedByString:@"/"][3];
CWInterface *iface = [CWInterface interfaceWithName:ifName];
NSLog(@"%@ status changed: current ssid is %@, security is %ld",
ifName, iface.ssid, iface.security);
}];
}
int main(int argc, char *argv[])
{
/* Get a list of all wifi interfaces, and build an array of SCDynamicStore keys to monitor */
NSSet *wifiInterfaces = [CWInterface interfaceNames];
NSMutableArray *scKeys = [[NSMutableArray alloc] init];
[wifiInterfaces enumerateObjectsUsingBlock:^(NSString *ifName, BOOL *stop)
{
[scKeys addObject:
[NSString stringWithFormat:@"State:/Network/Interface/%@/AirPort", ifName]];
}];
/* Connect to the dynamic store */
SCDynamicStoreContext ctx = { 0, NULL, NULL, NULL, NULL };
SCDynamicStoreRef store = SCDynamicStoreCreate(kCFAllocatorDefault,
CFSTR("myapp"),
wifi_network_changed,
&ctx);
/* Start monitoring */
SCDynamicStoreSetNotificationKeys(store,
(__bridge CFArrayRef)scKeys,
NULL);
CFRunLoopSourceRef src = SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault, store, 0);
CFRunLoopAddSource([[NSRunLoop currentRunLoop] getCFRunLoop],
src,
kCFRunLoopCommonModes);
[[NSRunLoop currentRunLoop] run];
}