Ethernet / Wi-Fi Network Change Detection

I want to determine when the network changes from Ethernet to Wi-Fi (or Wi-Fi to Ethernet). I want the supervisor to notify me of this change.

reachability is not good enough - it always returns ReachableViaWiFi for both cases.

PS - Earlier there were some questions on this topic, but none of them has a good answer, and since these questions are more than a year old, maybe someone will already know how to do this.

+9
swift macos
source share
2 answers

You can access the network settings through the SystemConfiguration module, which will help you access the system settings. Saving is currently in the default location /Library/Preferences/SystemConfiguration/preferences.plist .

From then on, you can receive notifications from SCDynamicStore on SCDynamicStoreNotifyValue(_:_:) or receive the value SCDynamicStoreCopyValue(_:_:) .

Example for direct search of the current primary network service:

 var store = SCDynamicStoreCreate(nil, "Example" as CFString, nil, nil) var global = SCDynamicStoreCopyValue(store, "State:/Network/Global/IPv4" as CFString)! var pref = SCPreferencesCreate(nil, "Example" as CFString, nil) var service = SCNetworkServiceCopy(pref!, global["PrimaryService"] as! CFString) var interface = SCNetworkServiceGetInterface(service!) SCNetworkInterfaceGetInterfaceType(interface!) /// Optional("IEEE80211") -> Wi-Fi 

Or create a dynamic repository with a callback and set the notification keys to receive notifications, since every time the primary network service changes the notification, it will work:

 var callback: SCDynamicStoreCallBack = { (store, _, _) in /* Do anything you want */ } var store = SCDynamicStoreCreate(nil, "Example" as CFString, callback, nil) SCDynamicStoreSetNotificationKeys(store!, ["State:/Network/Global/IPv4"] as CFArray, nil) 
+8
source share

In launchd you can run a little bash script that will track the interfaces you are interested in and run something when they change.

Say your wired connection is en0 , you can run:

 ./netmon en0 

Save this script as netmon and make it executable with chmod +x netmon

 #!/bin/bash interface=$1 # Get current status of interface whose name is passed, eg en0 status(){ ifconfig $1 | awk '/status:/{print $2}' } # Monitor interface until killed, echoing changes in status previous=$(status $interface) while :; do current=$(status $interface) if [ $current != $previous ]; then echo $interface now $current previous=$current fi sleep 5 done 
+2
source share

All Articles