iPhone notification when wifi network changes

孤街醉人 提交于 2019-11-28 12:12:34
Nate

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.

SWIFT 4.1 version

I've extend my Reachability class with this functions:

let notificationName = "com.apple.system.config.network_change"

func onNetworkChange(_ name : String) {
    if (name == notificationName) {
        // Do your stuff
        print("Network was changed")
    }
}

func registerObserver() {
    let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), observer,
                                    { (nc, observer, name, _, _) -> Swift.Void in
                                        if let observer = observer, let name = name {
                                            let instance = Unmanaged<Reachability>.fromOpaque(observer).takeUnretainedValue()
                                            instance.onNetworkChange(name.rawValue as String)
                                        } },
                                    notificationName as CFString, nil, .deliverImmediately)
}

func removeObserver() {
    let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
    CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), observer, nil, nil)
}

Register observer on init and remove on deinit. Unfortunately there is no additional info about what exactly was changed but we take a chance to test current SSID for example. Hope this will helpful for somebody)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!