It is strange to find that CNCopyCurrentNetworkInfo has a memory leak, and only if the return value is null. There are two questions: Failed to get the SSID? Why is there a memory leak?

Why was obtaining the SSID unsuccessful?

I did a little bit of a search, and then I found the answer in the CNCopyCurrentNetworkInfo header file, so let’s see what’s in the header file

/ *! @function CNCopyCurrentNetworkInfo @discussion Returns the network information for the specified interface when the requesting application meets one of following 4 requirements -. 1. application is using CoreLocation API and has the user's authorization to access location. 2. application has used the NEHotspotConfiguration API to configure the current  Wi-Fi network. 3. application has active VPN configurations installed. 4. application has active NEDNSSettingsManager Configurations Installed. - An application that is linked against iOS 12.0 SDK and above must have the "com.apple.developer.networking.wifi-info" entitlement. - An application will receive a pseudo network information if it Is linked against an SDK before iOS 13.0, and if it fails to meet any of the above requirements. - An application will receive NULL if it is linked against iOS 13.0 SDK (or newer), and if it fails to meet any of the above requirements. - On Mac Catalyst Platform, to receive current Wi-Fi network information, an application must have "com.apple.developer.networking.wifi-info" entitlement and user's authorization to access location. Network Information dictionary will contain the following keys, and values: 
 @textblock Keys : Values ======================================= kCNNetworkInfoKeySSIDData : CFDataRef kCNNetworkInfoKeySSID : CFStringRef kCNNetworkInfoKeyBSSID : CFStringRef @/textblock 

Pseudo network information will contain "Wi-Fi" SSID and "00:00:00:00:00:00" BSSID. For China region, the SSID will be "WLAN". @param interfaceName Name of the interface you are interested in @result Network Information dictionary associated with the interface. Returns NULL if an error was encountered. You MUST release the returned value. * /
CFDictionaryRef __nullable
CNCopyCurrentNetworkInfo (CFStringRef interfaceName)
API_DEPRECATED_WITH_REPLACEMENT("[NEHotspotNetwork fetchCurrentWithCompletionHandler:]", ios(4.1.API_TO_BE_DEPRECATED), macCatalyst(14.0.API_TO_BE_DEPRECATED))
API_UNAVAILABLE(macos, tvos, watchos);
Copy the code

Prerequisites for obtaining wifi information:

  • Greater than or equal to iOS12, must be configured in the entitlement com.apple.developer.net working. The wifi – info, value is YES. This is equivalent to adding Access WiFi Infomation to the Capability.

  • If it’s less than or equal to iOS13, one of the four conditions has to be met.

    • The user agrees to obtain the address permission
    • NEHotspotConfiguration API configured Wi-Fi (not tried)
    • VPN Configurations installed (not tried)
    • NEDNSSettingsManager Configurations installed (not tried)
  • Greater than or equal to iOS14, can use the new API [NEHotspotNetwork fetchCurrentWithCompletionHandler:]

With these Settings, Wifi information should be available, and memory leaks are gone.

Why is there a memory leak?

Get the SSID code first

+ (NSString *_Nullable)getDeviceSSID
{
    NSString *wifiName = nil;
    CFArrayRef wifiInterfaces = CNCopySupportedInterfaces(a);if(! wifiInterfaces) {return nil;
    }
    NSArray *interfaces = (__bridge NSArray *)wifiInterfaces;
    for (NSString *interfaceName in interfaces) {
        CFDictionaryRef dictRef = CNCopyCurrentNetworkInfo((__bridge CFStringRef)(interfaceName));
        if (dictRef) {
            NSDictionary *networkInfo = (__bridge NSDictionary *)dictRef;
            wifiName = [networkInfo objectForKey:(__bridge NSString *)kCNNetworkInfoKeySSID];
            CFRelease(dictRef);
            break; }}CFRelease(wifiInterfaces);
    return wifiName;
}
Copy the code

If wifiInterfaces is nil, then there is no way to release, and is CNCopySupportedInterfaces return values must be released.