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

我们拥有的

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

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

我们想要构建

为了提高应用程序的可用性,我们想向用户显示他当前的位置。使用Apples本地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 ""
}

此解决方案有效(在设置了适当的权利之后),但是我只能读取当前连接的访问点的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
}

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

问题

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

也许有某种方法可以使用MobileWiFi.framework(请参阅this link)来做到这一点,但是我无法全神贯注地在Swift中做这件事(对于iOS开发来说,这是一个初学者)。

最佳答案

恐怕不可能在没有越狱的设备上实现这一点。

我为此找到了some code,但是它已经过时了。我认为您不会在iOS 3/4设备上使用它。
NEHotspotHelper仅在“设置”->“无线”页面处于事件状态时有效。您可以在那里获得信号强度,但是我不确定它将如何工作。
MobileWiFi.framework需要授权,而没有jailbreak则无法设置。

有用的链接:
Technical Q&A QA1942

唯一的选择可能是iBeacons或QR(AR)。

10-08 20:22