How do I use CaptiveNetwork to get the current WiFi Hotspot Name
Asked Answered
H

4

26

I need to get the name of the currently connected Wi-Fi hotspot, e.g. "BT OpenZone"

I have been told it can be done with CaptiveNetwork specifically CNCopyCurrentNetworkInfo

My code so far:

#import <SystemConfiguration/CaptiveNetwork.h>
...

// Get the dictionary containing the captive network infomation
CFDictionaryRef captiveNtwrkDict = CNCopyCurrentNetworkInfo(kCNNetworkInfoKeySSID);

// Get the count of the key value pairs to test if it has worked
int count = CFDictionaryGetCount(captiveNtwrkDict);
NSLog(@"Count of dict:%d",count);

When the code runs on a device in a WiFi hotspot the captiveNtwrkDict is nil.

Has anyone managed to get it working? I cant find much documentation or any example code examples on CaptiveNetworks... any help would be much appreciated.

Hexad answered 17/1, 2011 at 11:16 Comment(0)
L
27

You need to find out which networks are available, and then pass them into CNCopyCurrentNetworkInfo. For example:

CFArrayRef myArray = CNCopySupportedInterfaces();
CFDictionaryRef myDict = CNCopyCurrentNetworkInfo(CFArrayGetValueAtIndex(myArray, 0));

...and you can then use the kCNNetworkInfoKeySSID on the dictionary you've got back (myDict) to find out the SSID. Don't forget to release/manage memory appropriately.

Lovash answered 17/1, 2011 at 15:28 Comment(2)
Can you please add entire function as i have imported cnnetwork and added this code. but my application is crashing on second line EXC_BAD_ACCESSElsie
m also facing the same problem of crash and m not getting how to fix this and in my case value of myArray is nil, m not getting any value from CNCopySupportedInterface();Jericajericho
B
24

UPDATE FOR iOS 12, swift 4.2

iOS 12

You must enable Access WiFi Information from capabilities.

Important To use this function in iOS 12 and later, enable the Access WiFi Information capability for your app in Xcode. When you enable this capability, Xcode automatically adds the Access WiFi Information entitlement to your entitlements file and App ID. Documentation link

Swift4.2

public class SSID {
    class func fetchSSIDInfo() -> String {
        var currentSSID = ""
        if let interfaces = CNCopySupportedInterfaces() {
            for i in 0..<CFArrayGetCount(interfaces) {
                let interfaceName: UnsafeRawPointer = CFArrayGetValueAtIndex(interfaces, i)
                let rec = unsafeBitCast(interfaceName, to: AnyObject.self)
                let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)" as CFString)
                if let interfaceData = unsafeInterfaceData as? [String: AnyObject] {
                    currentSSID = interfaceData["SSID"] as! String
                    let BSSID = interfaceData["BSSID"] as! String
                    let SSIDDATA = interfaceData["SSIDDATA"]
                    debugPrint("ssid=\(currentSSID), BSSID=\(BSSID), SSIDDATA=\(SSIDDATA)")
                }
            }
        }
        return currentSSID
    }
}

UPDATE FOR iOS 10

CNCopySupportedInterfaces is no longer deprecated in iOS 10. (API Reference)

You need to import SystemConfiguration/CaptiveNetwork.h and add SystemConfiguration.framework to your target's Linked Libraries (under build phases).

Here is a code snippet in swift (RikiRiocma's Answer):

import Foundation
import SystemConfiguration.CaptiveNetwork

public class SSID {
    class func fetchSSIDInfo() ->  String {
        var currentSSID = ""
        if let interfaces:CFArray! = CNCopySupportedInterfaces() {
            for i in 0..<CFArrayGetCount(interfaces){
                let interfaceName: UnsafePointer<Void> = CFArrayGetValueAtIndex(interfaces, i)
                let rec = unsafeBitCast(interfaceName, AnyObject.self)
                let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)")
                if unsafeInterfaceData != nil {
                    let interfaceData = unsafeInterfaceData! as Dictionary!
                    currentSSID = interfaceData["SSID"] as! String
                }
            }
        }
    return currentSSID
    }
}

(Important: CNCopySupportedInterfaces returns nil on simulator.)

For Objective-c, see Esad's answer here and below

+ (NSString *)GetCurrentWifiHotSpotName {    
    NSString *wifiName = nil;
    NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
    for (NSString *ifnam in ifs) {
        NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        if (info[@"SSID"]) {
            wifiName = info[@"SSID"];
        }
    }
    return wifiName;
}

UPDATE FOR iOS 9

As of iOS 9 Captive Network is deprecated*. (source)

*No longer deprecated in iOS 10, see above.

It's recommended you use NEHotspotHelper (source)

You will need to email apple at [email protected] and request entitlements. (source)

Sample Code (Not my code. See Pablo A's answer):

for(NEHotspotNetwork *hotspotNetwork in [NEHotspotHelper supportedNetworkInterfaces]) {
    NSString *ssid = hotspotNetwork.SSID;
    NSString *bssid = hotspotNetwork.BSSID;
    BOOL secure = hotspotNetwork.secure;
    BOOL autoJoined = hotspotNetwork.autoJoined;
    double signalStrength = hotspotNetwork.signalStrength;
}

Side note: Yup, they deprecated CNCopySupportedInterfaces in iOS 9 and reversed their position in iOS 10. I spoke with an Apple networking engineer and the reversal came after so many people filed Radars and spoke out about the issue on the Apple Developer forums.

Britisher answered 14/10, 2015 at 18:1 Comment(2)
thanks for your thorough reply, NEHotspotHelper code isnt working on swift 3Shaikh
Do we need to add release/retain in the swift code?Stonwin
M
8

Easy to use code snippet(method):

  • Add SystemConfiguration.framework

  • import < SystemConfiguration/CaptiveNetwork.h>

  • use the below method

    + (NSString *)GetCurrentWifiHotSpotName {
    
        NSString *wifiName = nil;
        NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
        for (NSString *ifnam in ifs) {
            NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
    
            NSLog(@"info:%@",info);
    
            if (info[@"SSID"]) {
                wifiName = info[@"SSID"];
            }
        }
        return wifiName;
    }
    
Mcmahon answered 30/12, 2013 at 11:51 Comment(10)
your method works like a charm. Can we disable/enable Wifi through our own App ?Conard
Can we enable/disable wifi ?Conard
If your app is not for app-store you can achieve by hooking SBWiFiManager class in springboard to know more visit https://mcmap.net/q/535967/-enable-disable-wifi-on-non-jailbroken-ios-deviceMcmahon
@Duraiamuthan.H is this suppose to work for simulator as well, or only when running on actual device?Concerto
@RoyH I've not tested in simulator,I suppose actual deviceMcmahon
Nice solution its work for me too...I have a question related to the same..can i get more information of connected wifi network.?Flail
@premajanoti - Other than SSID,you can get BSSID and SSIDDATA which is a hex representation of SSID and you can't get other informations such as signal strength etc ... The following is sample response of the API { BSSID = "mac address of accesspoint"; SSID = "userfriendlyname"; SSIDDATA = base64ofSSID; }Mcmahon
@DougNull - You can not modify this to read RSSI you can use this code snippet to read BSSID,SSID and SSIDDATA.Mcmahon
It's better to use Apple's definitions of the key names instead of hardcoded values. kCNNetworkInfoKeySSID, kCNNetworkInfoKeyBSSID, kCNNetworkInfoKeySSIDDataDesinence
@DuraiAmuthan.H Does it provides device details that are connected with my WiFi? I want to get MAC address, device name etc. that are connected with WiFi router and I want to display this details in iPhone app.Forewing
M
2

Note that in Xcode 10 and iOS 12 you now need to enable the "Access Wifi Information" capability.

Source: https://openradar.appspot.com/43280182

Margarite answered 4/10, 2018 at 0:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.