You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xcode 15中成功获取iOS设备的WiFi SSID信息?

在Xcode 15中获取iOS设备WiFi SSID的解决方案

问题背景

我曾在Xcode 14中使用以下Swift代码正常获取设备所连接WiFi的SSID,但升级到Xcode 15后运行报错。已配置正确的位置权限和“Access WIFI Information”能力,运行时出现以下错误:

NEHotspotNetwork failed to communicate to helper server for Wi-Fi information request
NEHotspotNetwork nehelper sent invalid result code [5] for Wi-Fi information request
No available network

原代码

MainView.swift

import Foundation
import SystemConfiguration.CaptiveNetwork
import NetworkExtension

struct MainView: View {
       
    @State var newlocationManager = NewLocationManager()

    var body: some View {
        VStack {
            
            Button() {
                getWIFISSID()
            }label: {
                Text("get SSID")
            }
        }.task {
            
            try? await newlocationManager.requestUserAuthorization()
            try? await newlocationManager.startCurrentLocationUpdates()
            // remember that nothing will run here until the for try await loop finishes
            
        }
    }
       
    func getWIFISSID()  {
        NEHotspotNetwork.fetchCurrent(completionHandler: { (network) in
            if let unwrappedNetwork = network {
                let networkSSID = unwrappedNetwork.ssid
                 print("Network: \(networkSSID) and signal strength %d",  unwrappedNetwork.signalStrength)
            } else {
                print("No available network")
            }
        })
    }
}

#Preview {
    MainView()
}

NewLocationManager.swift

@Observable
class NewLocationManager {
    var location: CLLocation? = nil
    
    private let locationManager = CLLocationManager()
    
    func requestUserAuthorization() async throws {
        locationManager.requestWhenInUseAuthorization()
    }
    
    func startCurrentLocationUpdates() async throws {
        for try await locationUpdate in CLLocationUpdate.liveUpdates() {
            guard let location = locationUpdate.location else { return }

            self.location = location
        }
    }
}

解决方案

1. 替换WiFi信息获取方法

在iOS 16+及Xcode 15环境下,NEHotspotNetwork.fetchCurrent的权限限制更严格,建议改用CNCopyCurrentNetworkInfo(来自SystemConfiguration.CaptiveNetwork框架),该方法在配置正确权限的情况下更稳定。

修改getWIFISSID函数如下:

func getWIFISSID() {
    guard let interfaceNames = CNCopySupportedInterfaces() as? [String] else {
        print("No supported interfaces found")
        return
    }
    
    for interfaceName in interfaceNames {
        guard let networkInfo = CNCopyCurrentNetworkInfo(interfaceName as CFString) as? [String: AnyObject] else {
            continue
        }
        
        if let ssid = networkInfo[kCNNetworkInfoKeySSID as String] as? String {
            print("Network: \(ssid)")
            // 注意:CNCopyCurrentNetworkInfo无法直接获取信号强度,若需该信息需结合其他API(且需额外权限)
            return
        }
    }
    print("No available network")
}

2. 确认权限配置细节

  • 位置权限:Info.plist中必须添加NSLocationWhenInUseUsageDescription或NSLocationAlwaysAndWhenInUseUsageDescription,且用户已授权至少When In Use级别的位置权限。
  • Access WiFi Information能力:在Xcode的Signing & Capabilities面板中添加该能力,确保项目的Entitlements文件包含com.apple.developer.networking.wifi-info权限。
  • 测试环境:iOS模拟器无法获取真实WiFi信息,必须使用真实iOS设备测试。

3. 修复位置权限的异步处理逻辑

原代码中请求位置权限后未等待用户授权完成就执行后续操作,可能导致权限未生效时调用WiFi获取方法。修改NewLocationManager的授权方法,确保等待用户授权状态确认:

@Observable
class NewLocationManager {
    var location: CLLocation? = nil
    
    private let locationManager = CLLocationManager()
    
    func requestUserAuthorization() async throws {
        let status = locationManager.authorizationStatus
        if status == .notDetermined {
            try await withCheckedThrowingContinuation { continuation in
                let observer = NotificationCenter.default.addObserver(
                    forName: .CLLocationManagerDidChangeAuthorization,
                    object: locationManager,
                    queue: .main
                ) { [weak self] _ in
                    guard let self = self else { return }
                    NotificationCenter.default.removeObserver(observer)
                    let newStatus = self.locationManager.authorizationStatus
                    if newStatus == .authorizedWhenInUse || newStatus == .authorizedAlways {
                        continuation.resume()
                    } else {
                        continuation.resume(throwing: NSError(
                            domain: "LocationError",
                            code: -1,
                            userInfo: [NSLocalizedDescriptionKey: "位置授权被拒绝或未授予"]
                        ))
                    }
                }
                locationManager.requestWhenInUseAuthorization()
            }
        } else if status != .authorizedWhenInUse && status != .authorizedAlways {
            throw NSError(
                domain: "LocationError",
                code: -1,
                userInfo: [NSLocalizedDescriptionKey: "未获得有效位置授权"]
            )
        }
    }
    
    func startCurrentLocationUpdates() async throws {
        for try await locationUpdate in CLLocationUpdate.liveUpdates() {
            guard let location = locationUpdate.location else { return }
            self.location = location
        }
    }
}

完成以上修改后,在真实iOS设备上运行即可正常获取WiFi SSID信息。

内容的提问来源于stack exchange,提问作者joan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:34:51