简体   繁体   中英

How to check if WiFi is on or off in iOS Swift 2?

I want to check if the wifi is off then show alert to the user to check his/her connectivity.

I find code like this but it checks if there is an internet connection, not checking if the wifi is on or off:

func isConnectionAvailble()->Bool{

  var rechability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, "www.apple.com").takeRetainedValue()

  var flags : SCNetworkReachabilityFlags = 0

  if SCNetworkReachabilityGetFlags(rechability, &flags) == 0
  {
     return false
  }

  let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0
  let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
  return (isReachable && !needsConnection)
}

You can't.

With Apple's reachability class, you can distinguish three things according to the NetworkStatus struct:

typedef enum : NSInteger {
  NotReachable = 0,         // 1
  ReachableViaWiFi,         // 2
  ReachableViaWWAN          // 3
} NetworkStatus;
  1. You have neither WiFi nor mobile data connection.
  2. You have a WiFi connection, but you may or may not have a mobile data connection.
  3. You have a mobile data connection, but no WiFi connection.

You can't check whether WiFi is turned off, or whether WiFi is turned on but there is no WiFi network nearby, or whether Airplane mode has been turned on.

For mobile data, you can use the telephony class to find whether your device is capable of mobile data connections (iPhone and not iPad, and SIM card plugged in), and you can detect whether mobile data is disabled in the preferences of your application.

Found the following, which was really helpful for me (found on the Apple Developer Forums ). The below code works with Swift 4.

func fetchSSIDInfo() ->  String {  
    var currentSSID = ""  
    if let interfaces:CFArray = 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 unsafeInterfaceData != nil {  
                let interfaceData = unsafeInterfaceData! as Dictionary!  
                for dictData in interfaceData! {  
                    if dictData.key as! String == "SSID" {  
                        currentSSID = dictData.value as! String  
                    }  
                }  
            }  
        }  
    }  
    return currentSSID  
}  

You can then check if a device is connected to Wi-Fi by the following:

if fetchSSIDInfo() != nil { 
    /* Wi-Fi is Connected */ 
}

Not perfect, but if the device is not connected to a Wi-Fi Network, you could then ask the user to connect to a Wi-Fi Network:

let wifiNotifcation = UIAlertController(title: "Please Connect to Wi-Fi", message: "Please connect to your standard Wi-Fi Network", preferredStyle: .alert)
wifiNotifcation.addAction(UIAlertAction(title: "Open Wi-Fi", style: .default, handler: { (nil) in
     let url = URL(string: "App-Prefs:root=WIFI")

     if UIApplication.shared.canOpenURL(url!){
           UIApplication.shared.openURL(url!)
           self.navigationController?.popViewController(animated: false)
     }
}))
self.present(wifiNotifcation, animated: true, completion: nil)

Tested with swift 4 and swift 5

let nwPathMonitor = NWPathMonitor()
nwPathMonitor.pathUpdateHandler = { path in

    if path.usesInterfaceType(.wifi) {
        print("Path is Wi-Fi")
    } else if path.usesInterfaceType(.cellular) {
            print("Path is Cellular")
    } else if path.usesInterfaceType(.wiredEthernet) {
            print("Path is Wired Ethernet")
    } else if path.usesInterfaceType(.loopback) {
            print("Path is Loopback")
    } else if path.usesInterfaceType(.other) {
            print("Path is other")
    }
}

nwPathMonitor.start(queue: .main)

As already @abba_de_bo mentioned: you could fetch the current SSID and check if it's set or nil.

This is the answer Apple's Eskimo gave to this question:

The trick with using CF-based APIs from Swift is to get the data into 'Swift space' as quickly as possible.

func currentSSIDs() -> [String] {  
  guard let interfaceNames = CNCopySupportedInterfaces() as? [String] else {  
    return []  
  } 

  return interfaceNames.flatMap { 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  
  }  
}

Note that this returns an array of names; how you handle the non-standard cases (no elements, more than one element) is up to you.

Make sure you import SystemConfiguration.CaptiveNetwork . Otherwise the build will fail with on of those error messages:

  • Use of unresolved identifier 'CNCopySupportedInterfaces'
  • Use of unresolved identifier 'CNCopyCurrentNetworkInfo'
  • Use of unresolved identifier 'kCNNetworkInfoKeySSID'

You can take a look at the official Apple sample for Reachability: https://developer.apple.com/library/content/samplecode/Reachability/Introduction/Intro.html

var netStatus = reachability.currentReachabilityStatus()
var connectionRequired = reachability.connectionRequired()
var statusString = ""
switch netStatus {
    case NotReachable:
        break
    case ReachableViaWWAN:
        //DATA
        break
    case ReachableViaWiFi:
        //WIFI
        break

}

You can use this method to check:

First you import this framework:

import SystemConfiguration.CaptiveNetwork


func isWifiEnabled() -> Bool {

        var hasWiFiNetwork: Bool = false
        let interfaces: NSArray = CFBridgingRetain(CNCopySupportedInterfaces()) as! NSArray

        for interface  in interfaces {
           // let networkInfo = (CFBridgingRetain(CNCopyCurrentNetworkInfo(((interface) as! CFString))) as! NSDictionary)
            let networkInfo: [AnyHashable: Any]? = CFBridgingRetain(CNCopyCurrentNetworkInfo(((interface) as! CFString))) as? [AnyHashable : Any]
            if (networkInfo != nil) {
                hasWiFiNetwork = true
                break
            }
        }
        return hasWiFiNetwork;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM