CNCopyCurrentNetworkInfo not always returning the correct value

My App is able to communicate with a range of IP cameras. The cameras identify themselves with a specific SSID pattern. The user will be able to connect using the standard iOS settings App and upon return to my App can then use the features of the camera.


My viewer App ships with a few SDKs that support each camera manufacturer (at the moment 4). Some of the SDKs are not cheap to load and consume a lot of memory / CPU resources, so I will only load /unload the appropriate SDK upon determing the connected camera based on the SSID.


Determining the SSID has been explained in this document:

https://developer.apple.com/library/archive/qa/qa1942/_index.html

... according to which I should use the CoreNetwork set of functions like CNCopyCurrentNetworkInfo.


So, here is my code for detecting the current SSID:


    public static func fetchSSIDInfo() -> String {
        var currentSSID = ""
        if let interfaces = CNCopySupportedInterfaces() {
            for i in 0..<cfarraygetcount(interfaces) {<br="">                let interfaceName: UnsafeRawPointer = CFArrayGetValueAtIndex(interfaces, i)
                let rec = unsafeBitCast(interfaceName, to: AnyObject.self)
                let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)" as CFString)
                               
                if unsafeInterfaceData != nil {
                    let interfaceData = unsafeInterfaceData! as NSDictionary
                    currentSSID = interfaceData["SSID"] as! String
                   
                    print ("SSID INFO: actually read SSID from interface: \(currentSSID) ")
                } else {
                    print ("SSID INFO: no interface data available!")
                }
            }
        } else {
            print ("SSID INFO: can not copy supported interfaces")
        }
        return currentSSID
    }

The code will be called every 1 second during time of connection and then every 2-5 seconds if a device has been connected.

Here is a sample output:


SSID INFO: no interface data available!
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: can not copy supported interfaces
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: no interface data available!
SSID INFO: no interface data available!
SSID INFO: no interface data available!
SSID INFO: no interface data available!
SSID INFO: no interface data available!
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network
SSID INFO: actually read SSID from interface: Sebastian's Wi-Fi Network


You can see the problem. Sometimes, the SSID is detected, sometimes it isn't. The function will be called once a second.


This problem gets worse as soon as I connect a actual camera, then load the SDK, just to unload it a few seconds afterwards (based on the loss of correct SSID):


SSID INFO: actually read SSID from interface: SOME DEVICE 75B
SSID INFO: actually read SSID from interface: SOME DEVICE 75B
SSID INFO: actually read SSID from interface: SOME DEVICE 75B
SSID INFO: no interface data available!
SSID INFO: actually read SSID from interface: SOME DEVICE 75B
SSID INFO: actually read SSID from interface: SOME DEVICE 75B
SSID INFO: actually read SSID from interface: SOME DEVICE 75B
SSID INFO: actually read SSID from interface: SOME DEVICE 75B


Happy to hear suggestions.

Accepted Reply

I helped sebroth with this issue via another channel and thought I’d post our conclusions here.

Why

CNCopyCurrentNetworkInfo
would return
NULL
sometimes (when the system is under load) is not clear here.

It seems that this is a poor interaction between iOS and sebroth’s configuration. Apparently they had about 900 known Wi-Fi networks configured on the device, and that was causing a system component (

wifid
) to run out of memory. It then crashed, which is why
CNCopyCurrentNetworkInfo
returned
NULL
.

The user-level workaround for this was for sebroth to reset their network settings (Settings > General > Reset > Reset Network Settings). This cleared the huge list of known networks, which prevented the crash, which allowed

CNCopyCurrentNetworkInfo
to work as expected.

sebroth also filed a bug about this (r. 35842343) and we’ve done some work in iOS 12 to reduce the memory use within

wifid
, which will hopefully reduce the occurrences of this problem in the future.

Share and Enjoy

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

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

Replies

Have found this discussion and Swift code:

https://forums.developer.apple.com/message/181456#181456


And will test.

And will test.

Please do. Specifically, look at my post on that thread. All the versions that use

unsafeBitCast(_:to:)
are not fit for purpose IMO.

Share and Enjoy

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

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

Hi eskimo,


Thank you for helping.

The code snippet does improve the situation, but I'm still seeing data not being copied properly.


Here is the code:


    public static func fetchSSIDInfo() -> String {
        guard let interfaceNames = CNCopySupportedInterfaces() as? [String] else {
            return "NO-INTERFACE"
        }
        return interfaceNames.compactMap { name in
            guard let info = CNCopyCurrentNetworkInfo(name as CFString) as? [String:AnyObject] else {
                return nil
            }
            guard let ssid = info[kCNNetworkInfoKeySSID as String] as? String else {
                return nil
            }
            return ssid
            }
            .filter({ (ssid) -> Bool in
                !ssid.isEmpty
                }
            )
            .first ?? "NONE"
    }


Once in a while, i will get "NONE".

It might happen after the App has done some sort of communication with the camera.

Should I simply try reading again?


Seb

Have extended the code as follows:


    public static func fetchSSIDInfo() -> String {
        for i in (0..<3) {
            let ssid = readSSID()
            print ("SSID: \(Date()): \(i), \(ssid)")
            if !ssid.isEmpty {
                return ssid
            }
        }
        
        return ""
    }
   
    private static func readSSID() -> String {
        guard let interfaceNames = CNCopySupportedInterfaces() as? [String] else {
            return ""
        }
        return interfaceNames.compactMap { name in
            guard let info = CNCopyCurrentNetworkInfo(name as CFString) as? [String:AnyObject] else {
                return nil
            }
            guard let ssid = info[kCNNetworkInfoKeySSID as String] as? String else {
                return nil
            }
            return ssid
            }
            .filter({ (ssid) -> Bool in
                !ssid.isEmpty
                }
            )
            .first ?? ""
    }


So let's see the log:


SSID: 2018-06-21 04:14:07 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:07 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:08 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:08 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:09 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:09 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:09 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:10 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:10 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:10 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:11 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:11 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:11 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:12 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:12 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:13 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:13 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:13 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:14 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:14 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:15 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:15 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:15 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:16 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:16 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:16 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:17 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:17 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:17 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:17 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:18 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:18 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:19 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:19 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:19 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:20 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:20 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:21 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:21 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:21 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:22 +0000: 0,
SSID: 2018-06-21 04:14:22 +0000: 1,
SSID: 2018-06-21 04:14:22 +0000: 2,
SSID: 2018-06-21 04:14:22 +0000: 0,
SSID: 2018-06-21 04:14:22 +0000: 1,
SSID: 2018-06-21 04:14:22 +0000: 2,
SSID: 2018-06-21 04:14:23 +0000: 0,
SSID: 2018-06-21 04:14:23 +0000: 1,
SSID: 2018-06-21 04:14:23 +0000: 2,
SSID: 2018-06-21 04:14:23 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:24 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:24 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:24 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:25 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:25 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:25 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:26 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:26 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:27 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:27 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:27 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:28 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:28 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:29 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:29 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:29 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:30 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:30 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:31 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:31 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:31 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:32 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:32 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:33 +0000: 0,
SSID: 2018-06-21 04:14:33 +0000: 1,
SSID: 2018-06-21 04:14:33 +0000: 2,
SSID: 2018-06-21 04:14:33 +0000: 0,
SSID: 2018-06-21 04:14:33 +0000: 1,
SSID: 2018-06-21 04:14:33 +0000: 2,
SSID: 2018-06-21 04:14:33 +0000: 0,
SSID: 2018-06-21 04:14:33 +0000: 1,
SSID: 2018-06-21 04:14:33 +0000: 2,
SSID: 2018-06-21 04:14:33 +0000: 0,
SSID: 2018-06-21 04:14:33 +0000: 1,
SSID: 2018-06-21 04:14:33 +0000: 2,
SSID: 2018-06-21 04:14:33 +0000: 0,
SSID: 2018-06-21 04:14:33 +0000: 1,
SSID: 2018-06-21 04:14:33 +0000: 2,
SSID: 2018-06-21 04:14:35 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:35 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:35 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:35 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:36 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:36 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:37 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:37 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:37 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:38 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:38 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:38 +0000: 0, IPCAM M121 F63
SSID: 2018-06-21 04:14:39 +0000: 0, IPCAM M121 F63



The gaps start appearing once I download thumbnails / or cancel downloads or in general just use the app.

This is starting to look more like a OS issue than actualy API / SDK usage issue. Why `CNCopyCurrentNetworkInfo` would return NULL sometimes (when the system is under load) is not clear here.


Another direction of though is whether CNCopyCurrentNetworkInfo has any expectation for the calling thread. I noticed the SSID to pretty consistently not show up, once I started to interact with the App UI as well (re-configure a collection view layout repeatedly). I have now wrapped the SSID function like so:


return DispatchQueue.main.sync(execute: { () -> String in
  return CameraConnection.fetchSSIDInfo()
})


This seem to have helped a bit. Will continue to test.

I helped sebroth with this issue via another channel and thought I’d post our conclusions here.

Why

CNCopyCurrentNetworkInfo
would return
NULL
sometimes (when the system is under load) is not clear here.

It seems that this is a poor interaction between iOS and sebroth’s configuration. Apparently they had about 900 known Wi-Fi networks configured on the device, and that was causing a system component (

wifid
) to run out of memory. It then crashed, which is why
CNCopyCurrentNetworkInfo
returned
NULL
.

The user-level workaround for this was for sebroth to reset their network settings (Settings > General > Reset > Reset Network Settings). This cleared the huge list of known networks, which prevented the crash, which allowed

CNCopyCurrentNetworkInfo
to work as expected.

sebroth also filed a bug about this (r. 35842343) and we’ve done some work in iOS 12 to reduce the memory use within

wifid
, which will hopefully reduce the occurrences of this problem in the future.

Share and Enjoy

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

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