36

Until today I used the CaptiveNetwork Interface to display the name of the currently connected Wifi. The iOS 9 Prerelease reference already stated, that the CaptiveNetwork methods are depracted now, but they still worked at the beginning.

With the newest version Apple seems to have blocked this calls already (maybe due to privacy concerns?).

Is there any other way to get the name of the current Wifi?

This is how I obtained the SSID until today, but you only get nil now:

#import <SystemConfiguration/CaptiveNetwork.h>

NSString *wifiName = nil;  
NSArray *interFaceNames = (__bridge_transfer id)CNCopySupportedInterfaces(); 

for (NSString *name in interFaceNames) { 
    NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)name); 

    if (info[@"SSID"]) { 
        wifiName = info[@"SSID"]; 
    } 
} 
David H
  • 40,852
  • 12
  • 92
  • 138
Thyraz
  • 2,412
  • 2
  • 21
  • 23

8 Answers8

32

Register your app as Hotspot helper.

#import <NetworkExtension/NetworkExtension.h>  

NSArray * networkInterfaces = [NEHotspotHelper supportedNetworkInterfaces];  
NSLog(@"Networks %@",networkInterfaces);  

UPDATE (Sept. 11th, 2015)

The following Captive Network APIs have been re-enabled in the latest version of iOS 9 instead.

  • CNCopySupportedInterfaces
  • CNCopyCurrentNetworkInfo

UPDATE (Sept. 16th, 2015)

If you still prefer to use NetworkExtension and Apple gave you permission to add the entitlements, then you can do this to get the wifi information:

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;
}

NetworkExtension provides you some extra information as secure, auto joined or the signal strength. And it also allows you to set credential to wifis on background mode, when the user scans wifis around.

Michael
  • 6,451
  • 5
  • 31
  • 53
Pablo A.
  • 2,042
  • 1
  • 17
  • 27
  • Ok, seems like a way that might be possible. But it's questionable if we get allowed to use the hotspot helper entitlements just to display the current WiFi SSID, as this entitlements needs to be requested from apple by email. Have you already used it that way? – Thyraz Jul 24 '15 at 07:06
  • 2
    Its not working...its returning NIL as CNCopySupportedInterfaces() does too – Wasim Ahmed Jul 24 '15 at 07:35
  • You first need to register your app as Hotspot Helper via email https://forums.developer.apple.com/message/30657#30657 – Pablo A. Jul 24 '15 at 08:14
  • 4
    @Forke lewiguez was the first who answered that Apple has reenabled the old methods. And Apple refuses requests for hotspot helper entitlements if you are not a hotspot helper app. So lewiguez answered the question about the same time, as Apple wrote me a mail, that I won't get the entitlements but that they reactivated the old methods due to the huge amount of requests they received. – Thyraz Sep 28 '15 at 08:49
  • 1
    I'm not sure, are you able to use the entitlements in In-House apps with a Distribution provisioning profile? I haven't found information about this and can't seem to make it work... – lewiguez Nov 04 '15 at 22:23
  • I have been accepted for the network entitlement but my supportedNetworkInterfaces array is nil, is my entitlement not working or is this normal behavior? – Steven B. Jun 07 '16 at 11:09
  • @Steven.B did you solve this issue? I have the same problem. – Keselme Aug 05 '18 at 10:30
  • @Keselme I'm sorry but I did not solve this issue. Eventually, the project got canceled and I stopped working on the hotspotHelper. – Steven B. Aug 06 '18 at 11:11
11

In the GM for iOS 9, it seems like this is enabled again. In fact, it's not even listed as deprecated in the online documentation, however the CaptiveNetwork header file does have the following:

CNCopySupportedInterfaces (void) __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_8, __MAC_NA, __IPHONE_4_1, __IPHONE_9_0, CN_DEPRECATION_NOTICE);

So, it is working in the iOS 9 GM, but not sure for how long :)

lewiguez
  • 3,813
  • 1
  • 25
  • 40
9

The answer by abdullahselek is still correct even for Swift 4.1 and 4.2.

A small caveat is that now in iOS 12, you must go to the capabilities section of your app project and enable the Access WiFi Information feature. It will add an entitlement entry to your project and allow the function call CNCopyCurrentNetworkInfo to work properly.

If you do not do this, that function simply returns nil. No errors or warnings at runtime about the missing entitlement will be displayed.

For more info, see the link below to Apple's documentation.

https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo

FerrousGuy
  • 138
  • 1
  • 9
8

Confirm on 2017-April-27, Captive Network is still working for Swift 3.1, XCode 8.3

For Swift > 3.0

func printCurrentWifiInfo() {
  if let interface = CNCopySupportedInterfaces() {
    for i in 0..<CFArrayGetCount(interface) {
      let interfaceName: UnsafeRawPointer = CFArrayGetValueAtIndex(interface, i)
      let rec = unsafeBitCast(interfaceName, to: AnyObject.self)
      if let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)" as CFString), let interfaceData = unsafeInterfaceData as? [String : AnyObject] {
        // connected wifi
        print("BSSID: \(interfaceData["BSSID"]), SSID: \(interfaceData["SSID"]), SSIDDATA: \(interfaceData["SSIDDATA"])")
      } else {
        // not connected wifi
      }
    }
  }
}

For Objective-C

NSArray *interFaceNames = (__bridge_transfer id)CNCopySupportedInterfaces();

for (NSString *name in interFaceNames) {
  NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)name);

  NSLog(@"wifi info: bssid: %@, ssid:%@, ssidData: %@", info[@"BSSID"], info[@"SSID"], info[@"SSIDDATA"]);
 }
Gabriel Jensen
  • 4,082
  • 1
  • 17
  • 14
nuynait
  • 1,912
  • 20
  • 27
4

As mentioned before CaptiveNetwork works well with Xcode 8.3 and upper. Here are code snippets for both Swift 3, Swift 4 and Objective-C.

Swift 3 & 4

import SystemConfiguration.CaptiveNetwork

internal class SSID {

    class func fetchSSIDInfo() -> [String: Any] {
        var interface = [String: Any]()
        if let interfaces = CNCopySupportedInterfaces() {
            for i in 0..<CFArrayGetCount(interfaces){
                let interfaceName = CFArrayGetValueAtIndex(interfaces, i)
                let rec = unsafeBitCast(interfaceName, to: AnyObject.self)
                guard let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)" as CFString) else {
                    return interface
                }
                guard let interfaceData = unsafeInterfaceData as? [String: Any] else {
                    return interface
                }
                interface = interfaceData
            }
        }
        return interface
    }

}

Objective-C

#import <SystemConfiguration/CaptiveNetwork.h>

+ (NSDictionary *)fetchSSIDInfo
{
    NSArray *interFaceNames = (__bridge_transfer id)CNCopySupportedInterfaces();
    for (NSString *name in interFaceNames)
    {
        NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)name);
        return info;
    }
    return nil;
}
abdullahselek
  • 7,893
  • 3
  • 50
  • 40
  • Can I get the received signal strength indicator (RSSI) from the wifi networks along with SSID using `CaptiveNetwork`? Is there any sample code for it? I use Objective-C in Xcode 9.0.1. – santobedi Jun 20 '18 at 07:04
  • As I know, there is no way to get wifi signal strength in apps that don't use [NEHotspotHelper](https://developer.apple.com/documentation/networkextension/nehotspothelper). You can find signal strength from **NEHotspotNetwork**’s `signalStrength` property. – abdullahselek Jun 20 '18 at 07:55
  • [It](https://stackoverflow.com/questions/32970711/is-it-possible-to-get-wifi-signal-strength-in-ios-9/32971064) suggests that I need to get permission from Apple to use `NEHotspotHelper`. Is it true? I write my iOS app for research use only (I won't submit in App store), hence I don't have paid iOS certificate. Can I still use `NEHotspotHelper`? – santobedi Jun 20 '18 at 08:10
  • Yes, it's true. I think you can't use. – abdullahselek Jun 20 '18 at 08:14
  • Starting with iOS 13, the CNCopyCurrentNetworkInfo API will no longer return valid Wi-Fi SSID and BSSID information. Instead, the information returned by default will be: SSID: “Wi-Fi” or “WLAN” (“WLAN" will be returned for the China SKU) BSSID: "00:00:00:00:00:00" – abdullahselek Aug 08 '19 at 07:38
  • Is there any way to get signal strength of nearby Wi-Fi devices similar to Bluetooth Low Energy beacons using an iPhone? Has anything been updated? – santobedi Aug 08 '19 at 07:45
  • Case for **NEHotspotHelper** is still same, if you want to receive beacons signal strength I guess you can use `rssi` of [CLBeacon](https://developer.apple.com/documentation/corelocation/clbeacon). – abdullahselek Aug 08 '19 at 08:15
  • I am aware of the [CLBeacon](https://developer.apple.com/documentation/corelocation/clbeacon?language=objc) and I'm using it to access RSS information from iBeacons. I want to access RSS info of Wi-Fi devices too. Is it possible at present using an iPhone? I'm able to do it using an Android phone. – santobedi Aug 08 '19 at 08:46
2

This should be working now with iOS 13.3. I'm using a related Pod library that uses the exact function in Objc and with a Swift wrapper.

https://github.com/Feghal/FGRoute

Nick N
  • 984
  • 9
  • 22
  • great! But how do I get the list now? – ink Feb 28 '20 at 03:09
  • @ink You can't get the list of Wifi's from iOS. See this thread. https://stackoverflow.com/questions/49525912/how-to-get-available-all-wifi-network-name-listing-in-ios-using-swift The solution that I'm using is a hardware device that has a stand up wifi access point and a REST service on the board. It gets the wifi list and returns it over REST. It's an IoT use case like a remote door opener app. – Nick N Apr 25 '20 at 14:09
1

CaptiveNetwork is still working. Due to many requests Apple may have reinstated the API's.

Using CaptiveNetwork we can get the SSID of the WiFi network. It even works in iOS 10.

#import <SystemConfiguration/CaptiveNetwork.h>

NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)name);

Here is the output:

Printing description of info:
{
    BSSID = "5*:**:**:**:**:**";
    SSID = Cisco12814;
    SSIDDATA = <43697363 6f313238 3134>;
}
Ranjith
  • 425
  • 6
  • 8
1

CaptiveNetwork is still working. But you will need to add this:

com.apple.developer.networking.wifi-info = true inside your Entitlements.plist.

Plus, you need to be Enable the Access WiFi Information in the App ID part in your developer.apple.com portal.

Be sure, to clean your environment, generate new provisioning profile after enabling option "Access WiFi Information" in the App ID.

Tô Minh Tiến
  • 1,131
  • 11
  • 6