最近项目有个Heatmap的功能,大致就是需要扫描附近WiFi网络,并且获取他们的信号强度,BSSID, SSID、加密等级等的功能。
技术选型:
通过一顿搜索,得知WiFi可以通过NEHotspotHelper 去获取对应的信息。
支持的信息如下:
@available(iOS 9.0, *)
open class NEHotspotNetwork : NSObject {
/**
* @property SSID
* @discussion The SSID of the Wi-Fi network.
*/
@available(iOS 9.0, *)
open var ssid: String { get }
/**
* @property BSSID
* @discussion The BSSID of the Wi-Fi network.
*/
@available(iOS 9.0, *)
open var bssid: String { get }
/**
* @property securityType
* @discussion The security type of the Wi-Fi network.
*/
@available(iOS 15.0, *)
open var securityType: NEHotspotNetworkSecurityType { get }
@available(iOS 14.0, *)
open class func fetchCurrent(completionHandler: @escaping (NEHotspotNetwork?) -> Void)
@available(iOS 14.0, *)
open class func fetchCurrent() async -> NEHotspotNetwork?
}
@available(iOS 9.0, *)
extension NEHotspotNetwork {
/**
* @property signalStrength
* @discussion
* The signal strength for the Wi-Fi network. The value lies within
* the range 0.0 (weak/no signal) to 1.0 (strong signal).
*/
@available(iOS 9.0, *)
open var signalStrength: Double { get }
/**
* @property secure
* @discussion Indicates whether the network is secure
*/
@available(iOS 9.0, *)
open var isSecure: Bool { get }
/**
* @property autoJoined
* @discussion
* Indicates whether the network was joined automatically
* (YES) or joined by the user (NO).
*/
@available(iOS 9.0, *)
open var didAutoJoin: Bool { get }
/**
* @property justJoined
* @discussion
* Indicates whether the network was just joined. Useful in the
* Maintaining state to differentiate whether the Maintain command
* is for the initial join, or the subsequent periodic callback.
*/
@available(iOS 9.0, *)
open var didJustJoin: Bool { get }
/**
* @property chosenHelper
* @discussion
* Indicates whether the HotspotHelper is the chosen helper for
* the network. The NEHotspotNetwork must have been instantiated via a
* call to the +[NEHotspotHelper supportedNetworkInterfaces] method. This
* is useful to restore state after the HotspotHelper application is quit
* and restarted.
*/
@available(iOS 9.0, *)
open var isChosenHelper: Bool { get }
@available(iOS 9.0, *)
open func setConfidence(_ confidence: NEHotspotHelperConfidence)
@available(iOS 9.0, *)
open func setPassword(_ password: String)
}
基本符合我们的需求预期,于是开整:
if #available(iOS 13.0, *) {
Task {
if #available(iOS 14.0, *) {
NEHotspotNetwork.fetchCurrent { info in
self.wifiName = info?.ssid ?? ""
let signalStrength = info?.signalStrength
let helper = info?.isChosenHelper
result(true, self.wifiName, signalStrength ?? 0)
}
} else {
// Fallback on earlier versions
XCGLog.info("不支持当前系统版本")
result(false, "", 0)
}
}
} else {
// Fallback on earlier versions
XCGLog.info("不支持当前系统版本")
result(false, "", 0)
}
注意
-
NEHotspotNetwork.fetchCurrent
的系统支持版本最低是iOS14.0,其中securityType
需要iOS15.0才能支持。 - 如果你按照上面操作,依然无法获取
signalStrength
,返回一直为0. 这时你需要看下isChosenHelper
返回是否为false。如果是,那么恭喜,我们需要去官方开发者平台申请对应权限,才能够获取。 - 获取权限方式,参考NEHotspotHelper权限获取方式,挺麻烦的,后面如果我通过了,再来反馈申请时间多长。
4.最后提醒,如果我们的目的是想表明当前网络好还是不好,苹果工程师不建议我们通过使用信号值这种方式去表现,建议通过文件测速的方式,去判断当前网络的有效可用性。相关论坛讨论发言稿地址参考 。 当然,如果只是简单的展现信号值,这种方式是可取的。