Search code examples
iphoneioswifijailbreak

iPhone notification when wifi network changes


This is for a tweak, so the target is jailbroken devices, and not the app store. I have tried hooking different methods in the SBWiFiManager but they either are called when the wifi strength changes (so continuously) or after quite delay after the network has changed.

Is there any other way to get a notification (or another method to hook) went the wifi network changes?

I know you can get the current SSID with public APIs now, but I need to be told when it changes.


Solution

  • One way to do this is to listen for the com.apple.system.config.network_change event from the Core Foundation Darwin notification center.

    Register for the event:

    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
                                    NULL, // observer
                                    onNotifyCallback, // callback
                                    CFSTR("com.apple.system.config.network_change"), // event name
                                    NULL, // object
                                    CFNotificationSuspensionBehaviorDeliverImmediately);
    

    Here's a sample callback:

    static void onNotifyCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
    {
        NSString* notifyName = (NSString*)name;
        // this check should really only be necessary if you reuse this one callback method
        //  for multiple Darwin notification events
        if ([notifyName isEqualToString:@"com.apple.system.config.network_change"]) {
            // use the Captive Network API to get more information at this point
            //  https://stackoverflow.com/a/4714842/119114
        } else {
            NSLog(@"intercepted %@", notifyName);
        }
    }
    

    See my link to another answer on how to use the Captive Network API to get the current SSID, for example.

    Note that although the phone I tested this on is jailbroken (iOS 6.1), I don't think this requires jailbreaking to work correctly. It certainly doesn't require the app being installed outside the normal sandbox area (/var/mobile/Applications/*).

    P.S. I haven't tested this exhaustively enough to know whether this event gives any false positives (based on your definition of a network change). However, it's simple enough just to store some state variable, equal to the last network's SSID, and compare that to the current one, whenever this event comes in.