swiftmacosswift2corewlan

Display all available WIFI connections with Swift in OS X


I'm trying to display all available WIFI connections. It doesn't work. Here is my code:

import Foundation
import CoreWLAN

var cwInterface = CWInterface()

do {
    let routers = try cwInterface.scanForNetworksWithSSID(nil)
    print(routers)
} catch let error as NSError {
    print("Error: \(error.localizedDescription)")
}

I don't get any result. What I'm doing wrong?


Solution

  • It works if you initialize CWInterface with an interface name, like "en1".

    But it's better to not use harcoded names, so we'll also use CWWiFiClient.sharedWiFiClient().interface() which returns the default WIFI interface.

    Example of a class to manage all this:

    class Discovery {
    
        var currentInterface: CWInterface
        var interfacesNames: [String] = []
        var networks: Set<CWNetwork> = []
    
        // Failable init using default interface
        init?() {
            if let defaultInterface = CWWiFiClient.sharedWiFiClient().interface(),
                   name = defaultInterface.interfaceName {
                self.currentInterface = defaultInterface
                self.interfacesNames.append(name)
                self.findNetworks()
            } else {
                return nil
            }
        }
    
        // Init with the literal interface name, like "en1"
        init(interfaceWithName name: String) {
            self.currentInterface = CWInterface(interfaceName: name)
            self.interfacesNames.append(name)
            self.findNetworks()
        }
    
        // Fetch detectable WIFI networks
       func findNetworks() {
            do {
                self.networks = try currentInterface.scanForNetworksWithSSID(nil)
            } catch let error as NSError {
                print("Error: \(error.localizedDescription)")
            }
        }
    
    }
    

    Call it with the default interface:

    if let discovery = Discovery() {
        print(discovery.networks)
        for network in discovery.networks {
            print(network.ssid!)
        }
    }
    

    Or with an interface name:

    let discovery = Discovery(interfaceWithName: "en1")
    let results = discovery.networks
    

    Results contains all the scanned networks:

    [<CWNetwork: 0x608000001bd0> [ssid=SomeNetworkName, bssid=xxxx, security=WPA Enterprise, rssi=xx, channel=<CWChannel: 0x600000004fb0> [channelNumber=11(2GHz), channelWidth={20MHz}], ibss=0], etc]