Greetings
I'm trying to get on iPad the SSID from the wifi I'm connected to. For that, I added the wifi entitlement and I'm requesting permission to the user for Location.
Once I have it, I'm using the function CNCopySupportedInterfaces to get the interfaces, but I can only receive the en0, which using the method CNCopyCurrentNetworkInfo returns nil.
I also tried using the NEHotspotNetwork.fetchCurrent and the SSID keeps being nil. So right now I'm drawing a blank. Is there any way to make it work? Thanks.
Don’t use CNCopySupportedInterfaces
. It’s been deprecated in favour of NEHotspotNetwork.fetchCurrent(completionHandler:)
.
I’ve not had any problems getting fetchCurrent(completionHandler:)
once I met the necessary criteria:
-
The device must actually be on Wi-Fi.
-
The app must be signed with the
com.apple.developer.networking.wifi-info
entitlement. -
The app must be authorised by the user to access Wi-Fi information. The most obvious way to get that authorisation is via Core Location.
I just re-tested this with my test app running on iOS 18.4.1 and it worked as I remembered. At this end of this post you’ll find the model-level code for that test app. This relies on a fetchWiFiInfo(…)
wrapper, because it needs to use different APIs on macOS and iOS. The iOS implementation of that wrapper looks like this:
enum WiFiInfo {
static func fetchWiFiInfo(_ completionHandler: @escaping (_ ssid: String?) -> Void) {
NEHotspotNetwork.fetchCurrent { networkQ in
DispatchQueue.main.async {
let ssid = networkQ?.ssid
completionHandler(ssid)
}
}
}
}
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
class Model: NSObject, ObservableObject, CLLocationManagerDelegate {
init(shouldStart: Bool = false) {
self.logger = Logger(subsystem: "com.example.apple-samplecode.QCurrentSSID", category: "model")
self.logger.log("init")
super.init()
if shouldStart {
self.locationManager.delegate = self
self.refreshSSID()
}
}
private let logger: Logger
// MARK: - SSID
@Published var ssid: String?
@Published var isRefreshingSSID: Bool = false
func refreshSSID() {
precondition( !self.isRefreshingSSID )
self.logger.log("will refresh SSID")
self.isRefreshingSSID = true
WiFiInfo.fetchWiFiInfo() { ssid in
self.ssid = ssid
self.logger.log("did refresh SSID, ssid: \(ssid ?? "-", privacy: .private)")
self.isRefreshingSSID = false
}
}
// MARK: - Location
@Published var locationState: LocationState = .notRequested
enum LocationState {
case notRequested
case unknown
case restricted
case denied
case authorised
var canRequestLocation: Bool {
switch self {
case .notRequested: return true
case .unknown: return true
case .restricted: return false
case .denied: return false
case .authorised: return false
}
}
}
@Published var isRequestingLocation: Bool = false
private let locationManager = CLLocationManager()
func requestLocation() {
precondition( !self.isRequestingLocation )
self.logger.log("will request location")
self.isRequestingLocation = true
self.locationManager.requestWhenInUseAuthorization()
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
precondition(Thread.isMainThread)
let newState: LocationState
switch self.locationManager.authorizationStatus {
case .notDetermined: newState = .unknown
case .restricted: newState = .restricted
case .denied: newState = .denied
case .authorizedAlways: newState = .authorised
case .authorizedWhenInUse: newState = .authorised
@unknown default: newState = .unknown
}
if newState != self.locationState {
self.locationState = newState
self.logger.log("did update location, state: \(".\(newState)", privacy: .public)")
if !self.isRefreshingSSID {
self.refreshSSID()
}
}
if self.isRequestingLocation {
self.isRequestingLocation = false
self.logger.log("did request location")
}
}
}