4

I need to differentiate between the iPhone/iPad user being connected to cellular versus wifi. Under the SCNetworkReachabilityFlag .isWWAN, Apple says:

The absence of this flag does not necessarily mean that a connection will never pass over a cellular network. If you need to robustly prevent cellular networking, read Avoiding Common Networking Mistakes in Networking Overview.

What this means is, if this flag is enabled, the user is most likely connecting via a cellular network, but it's not guaranteed. I read Avoiding Common Networking Mistakes but it is not helpful.

How can I be 100% sure that the user is on a cellular network (or not)?

My code looks like this:

let reachability = SCNetworkReachabilityCreateWithName(nil, "localhost")
var flags = SCNetworkReachabilityFlags()
if let reachability = reachability {
    SCNetworkReachabilityGetFlags(reachability, &flags)
}
let isConnectedToCellular = flags.contains(.isWWAN)

EDIT:

If you are using this code, be sure to call it on a background thread and not the main thread.

Mendo
  • 163
  • 1
  • 5
  • I suspect this isn't quite the right question. I assume you mean "how can I ensure that a connection is not made over cellular?" If that's the question, Apple's link is incorrect (or possibly just out of date). It's in "Platform-Specific Networking Technologies" in the same document: https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/Platform-SpecificNetworkingTechnologies/Platform-SpecificNetworkingTechnologies.html – Rob Napier Jan 18 '19 at 20:29
  • Correct. Thank you. – Mendo Jan 18 '19 at 20:31

2 Answers2

4

You can use Reachability.swift Either you use this, or get some idea on how some certain flow is made and works.

It has a Connection enum that goes like this:

public enum Connection: CustomStringConvertible {
        case none, wifi, cellular
        public var description: String {
            switch self {
            case .cellular: return "Cellular"
            case .wifi: return "WiFi"
            case .none: return "No Connection"
            }
        }
    }

And NetworkStatus:

public enum NetworkStatus: CustomStringConvertible {
    case notReachable, reachableViaWiFi, reachableViaWWAN
    public var description: String {
        switch self {
        case .reachableViaWWAN: return "Cellular"
        case .reachableViaWiFi: return "WiFi"
        case .notReachable: return "No Connection"
        }
    }
}

And from there you can do the following:

  1. Check if the device is connected to the mobile data / cellular Or Wifi.
  2. Observe reachability / internet connection.
Glenn Posadas
  • 12,555
  • 6
  • 54
  • 95
1

hope this help

   func getWiFiName() -> String? {
            var ssid: String?
            if let interfaces = CNCopySupportedInterfaces() as NSArray? {
                for interface in interfaces {
                    if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as! CFString) as NSDictionary? {
                        ssid = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String
                        break
                    }
                }
            }
            return ssid
        }

if this return nil then you'r connected over cellular if device connected to a wifi then it will return the wifi name (SSID) don't forget to turn on network extensions and access wifi information on project capabilities

THIS DOESNT WORK ON SIMULATOR (IT SHOULD BE REAL DEVICE)!!!! and add this two

import NetworkExtension

import SystemConfiguration.CaptiveNetwork