Is it safe to use 'com.apple.system.config.network_change' notification to detect network reachability?

Hello,


Is it safe to use 'com.apple.system.config.network_change' notification to detect network reachability changes? Or is it considered to be a private API? For now my code looks like this:

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
                                nil,
                                callback,
                                "com.apple.system.config.network_change" as CFString,
                                nil,
                                .deliverImmediately);

And then in callback I respond to the notification.


The problem is Reachability in iOS not always detects Wi-Fi switching. For instance, if we are switching from one Wi-Fi AP to the other that system already knows (because we have used it in the past) then it happens so fast that there's no 'Disconnected' event and I cannot track the actual switching moment. Solution above works but I am sure whether my app won't be rejected for publishing in the App Store.


Thanks!

Accepted Answer

This notification is considered public API, although I recommend that you use the symbolic constant,

kNotifySCNetworkChange
defined in
<notify_keys.h>
, rather the raw string.

Whether it will reliably fire on Wi-Fi to Wi-Fi switches is a complex issue. Are you interested in changes in SSID? Or changes in BSSID? Or both?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks a lot! Btw, is there any list or something where I can see which APIs are private/public? So I won't need to ask every time 🙂


I am actually interested in catching events of changing Wi-Fi APs or Wi-Fi <-> Cellular because if it changes then I want to ping my server to know if the network is really available. Because it happens sometimes that my users connect to the Wi-Fi without actual internet. And so iOS tells my application that network is reachable while it is not. But it's okay and I can handle it just pinging my server - if it won't return a response then there is no network. But I want to do it smart, not just don't ping server every few seconds or so, that's why I need to catch these notifications. So my idea is like this: Receive notification that user/system changed Wi-Fi AP (or switched to Cellular data) -> ping the server to know exactly whether there is internet in that particulae AP


Is it good idea or could I improve it somehow?


Thanks!

Btw, is there any list or something where I can see which APIs are private/public?

The keys in

<notify_keys.h>
are public; everything else is private.

I am actually interested in catching events of changing Wi-Fi APs …

I’m back asking the same question: Do you have AP changes (that is, a chang of BSSID) or network changes (a change of SSID)?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I need to catch SSID.

I need to catch SSID.

OK.

Earlier you wrote:

Receive notification that user/system changed Wi-Fi AP (or switched to Cellular data) -> ping the server to know exactly whether there is internet in that particulae AP

I think it’s reasonable to use the

kNotifySCNetworkChange
event for that. You might get some false positives, but those won’t be a significant problems.

I recommend that you debounce this signal, that is, coalesce these notifications and only send the ping after the network has stabilised.

Also, as with any reachability check I strongly recommend that you not prevent the user from doing something because you think the network is offline. Because of TOCTTOU issues you can never be sure where a specific request will actually work or not. So it’s fine to use a reachability check to guide your UI, but don’t prevent the user from doing something just because of your reachability check failed.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Great! Thanks a lot for your suggestions!


You said earlier that ‘Whether it will reliably fire on Wi-Fi to Wi-Fi switches is a complex issue.’ — can you provide any details why is it like this? Is it somehow related to iOS architecture? Or is it complicted in general?

can you provide any details why is it like this?

Because the semantics of this notification are not tightly nailed down. For example, a switch from one BSSID to another does not generally require IP-level software to reconfigure, so it’d be reasonable for this notification to not be posted in that case. In contrast a switch from one SSID to another can affect the IP environment, even if both the before and after environments look identical. For example, two NAT gateways may look identical on the ‘wire’ (that is, have the same network address, gateway address and DNS configuration, and even hand out the same IP address to your client) but they are not interchangeable (due to the state in the NAT itself). Thus I’d expect this notification to be posted on all SSID switches. The gotcha is that the (very limited) documentation for

kNotifySCNetworkChange
does not guarantee that.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Got it! Thanks a lot! 🙂😎

Hi eskimo,


"Whether it will reliably fire on Wi-Fi to Wi-Fi switches is a complex issue. Are you interested in changes in SSID? Or changes in BSSID? Or both?"


In my test, seems kNotifySCNetworkChange only works for ssid change, is there any way to detect bssid change or both, thanks.

Is it safe to use 'com.apple.system.config.network_change' notification to detect network reachability?
 
 
Q