获取接入点及其信号强度的列表

sch*_*rmu 5 ios swift

我目前正在尝试构建概念验证的iOS应用,以检查我们是否能够在不部署信标或任何其他硬件的情况下实现某种室内定位功能。

我们有什么

有一个数据库,其中包含我们建筑物中所有已注册的访问点,包括其X坐标和Y坐标。坐标被映射到横跨整个建筑物的定制网格。

该应用程序将使用我们的企业版发行,因此没有任何有关Apple Store要求的限制。该应用将仅在使用证书自动连接到正确的WiFi的设备上运行。

我们想要建造什么

为了提高应用程序的可用性,我们想向用户显示他当前的位置。使用Apple的本机CLLocation服务不够准确,因为我们在建筑物内运营。基本思想是获取所有附近的接入点(包括其BSSID和信号强度),并使用信号强度和接入点的位置数据库来计算或多或少的准确位置(请参见上文)。

到目前为止我尝试过的

使用SystemConfiguration.CaptiveNetwork获得BSSID

import SystemConfiguration.CaptiveNetwork

func getCurrentBSSID() -> String {
    guard let currentInterfaces = CNCopySupportedInterfaces() as? [String] else { return "" }
    for interface in currentInterfaces {
        print("Looking up BSSID info for \(interface)") // en0
        let SSIDDict = CNCopyCurrentNetworkInfo(interface as CFString) as! [String : AnyObject]
        return SSIDDict[kCNNetworkInfoKeyBSSID as String] as! String
    }
    return ""
}
Run Code Online (Sandbox Code Playgroud)

此解决方案有效(在设置了适当的权利之后),但是我只能读取当前连接的接入点的BSSID 。

使用UIStatusBarDataNetworkItemView于读出信号强度

private func wifiStrength() -> Int? {
    let app = UIApplication.shared
    var rssi: Int?
    guard let statusBar = app.value(forKey: "statusBar") as? UIView, let foregroundView = statusBar.value(forKey: "foregroundView") as? UIView else {
        return rssi
    }
    for view in foregroundView.subviews {
        if let statusBarDataNetworkItemView = NSClassFromString("UIStatusBarDataNetworkItemView"), view .isKind(of: statusBarDataNetworkItemView) {
            if let val = view.value(forKey: "wifiStrengthRaw") as? Int {
                rssi = val
                break
            }
        }
    }
    return rssi
}
Run Code Online (Sandbox Code Playgroud)

这很明显,它仅读取所连接的WiFi网络的信号强度,而不读取特定于接入点的信号强度。

有什么方法可以读取可用接入点(不是 WiFi网络)列表,包括其BSSID和信号强度?由于设备处于设备管理之下,因此我们无法越狱。

也许有某种方法可以使用它MobileWiFi.framework(请参阅此链接),但是我无法全神贯注地在Swift中进行开发(这是iOS开发的初学者)。

ARG*_*Geo 1

虽然很多资源都说在使用Apple“官方”框架时,您只能获取您的iPhone当前连接的网络的SSID。以下是解决方法:

\n\n
    \n
  1. 您可以使用NEHotspotConfigurationManager类,但首先您必须启用热点配置权利(属性列表键)。

  2. \n
  3. 您还可以使用NEHotspotHelper类(尽管它需要Apple 的许可)。为此,您需要申请网络扩展权利,然后修改您的配置文件以及一些其他操作。看看这个帖子以获取更多详细信息。

  4. \n
\n\n

这是如何使用 NEHotspotConfigurationManager 的代码片段:

\n\n
import NetworkExtension\n\nclass ViewController: UIViewController {\n\n    let SSID = ""\n\n    @IBAction func connectAction(_ sender: Any) {\n        let hotspotConfig = NEHotspotConfiguration(ssid: SSID, passphrase: "", isWEP: false)\n        NEHotspotConfigurationManager.shared.apply(hotspotConfig) {[unowned self] (error) in\n            if let error = error {\n                self.showError(error: error)\n            } else {\n                self.showSuccess()\n            }\n        }\n    }\n\n    @IBAction func disconnectAction(_ sender: Any) {\n        NEHotspotConfigurationManager.shared.removeConfiguration(forSSID: SSID)\n    }\n\n    private func showError(error: Error) {\n        let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)\n        let action = UIAlertAction(title: "Darn", style: .default, handler: nil)\n        alert.addAction(action)\n        present(alert, animated: true, completion: nil)\n    }\n\n    private func showSuccess() {\n        let alert = UIAlertController(title: "", message: "Connected", preferredStyle: .alert)\n        let action = UIAlertAction(title: "Cool", style: .default, handler: nil)\n        alert.addAction(action)\n        present(alert, animated: true, completion: nil)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是如何使用 NEHotspotHelper 的代码片段:

\n\n
import NetworkExtension\nimport SystemConfiguration.CaptiveNetwork\n\nfunc getSSID() -> String {\n\n    if #available(iOS 11.0, *) {\n\n        let networkInterfaces = NEHotspotHelper.supportedNetworkInterfaces()\n        let wiFi = NEHotspotNetwork()\n\n        let st = "SSID\xef\xbc\x9a\\(wiFi.SSID)\xef\xbc\x8c BSSID\xef\xbc\x9a\\(wiFi.BSSID)"\n        return st\n\n        for hotspotNetwork in NEHotspotHelper.supportedNetworkInterfaces() {\n\n            let signalStrength = hotspotNetwork.signalStrength\n            print(signalStrength)\n        }\n\n    } else {\n\n        let interfaces = CNCopySupportedInterfaces()\n        guard interfaces != nil else { \n            return "" \n        }\n        let if0: UnsafePointer<Void>? = CFArrayGetValueAtIndex(interfaces, 0)\n\n        guard if0 != nil else { \n            return "" \n        }             \n        let interfaceName: CFStringRef = unsafeBitCast(if0!, CFStringRef.self)\n        let dictionary = CNCopyCurrentNetworkInfo(interfaceName) as NSDictionary?\n\n        guard dictionary != nil else { \n            return "" \n        } \n\n    return String(dictionary![String(kCNNetworkInfoKeySSID)])\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n