使用私有API读取WiFi RSSI值

我正在开发一些不需要在App商店上工作的东西,所以我在使用私有API来满足我的需求方面没有任何问题我正在尝试使用MobileWiFi. framework to read the RSSI value for the wireless network the phone is currently connected to. I've included the MobileWiFi. framework to read the RSSI value for the wireless network the phone is currently connected to. I've included the MobileWiFi. framework to read the RSSI value for the wireless network the phone is currently connected to. I've included the https: //github.com/ Cykey/ ios-reversed-headers / tree/c613e45f3ee5ad9f85ec7d43906cf69ee812ec6a / MobileWiFi`标题,并使用桥接头将它们包含在我的swift项目中,并按如下方式编写代码。 请原谅,我是新手。

 import SystemConfiguration.CaptiveNetwork typealias _WiFiManagerClientCreate = @convention(c) (CFAllocator, CInt) -> UnsafeRawPointer typealias _WiFiManagerClientCopyDevices = @convention(c) (UnsafeRawPointer) -> CFArray typealias _WiFiDeviceClientCopyProperty = @convention(c) (UnsafeRawPointer, CFString) -> CFPropertyList if let libHandle = dlopen (Paths.ipConfiguration, RTLD_LAZY) { result = libHandle.debugDescription let _createManagerPtr = dlsym(libHandle, "WiFiManagerClientCreate") let _clientCopyDevicesPtr = dlsym(libHandle, "WiFiManagerClientCopyDevices") let _clientCopyPropertyPtr = dlsym(libHandle, "WiFiDeviceClientCopyProperty") if (_createManagerPtr != nil) && (_clientCopyDevicesPtr != nil) && (_clientCopyPropertyPtr != nil) { let _createManager = unsafeBitCast(_createManagerPtr, to: _WiFiManagerClientCreate.self) let _clientCopyDevices = unsafeBitCast(_clientCopyDevicesPtr, to: _WiFiManagerClientCopyDevices.self) let _clientCopyProperty = unsafeBitCast(_clientCopyPropertyPtr, to: _WiFiDeviceClientCopyProperty.self) let manager = _createManager(kCFAllocatorDefault, 0) let devices = _clientCopyDevices(manager) let client = CFArrayGetValueAtIndex(devices, 0) let data = _clientCopyProperty(client!, "RSSI" as CFString) let rssi = CFDictionaryGetValue(data as! CFDictionary, "RSSI_CTL_AGR") NSLog("RSSI: \(rssi)") } dlclose(libHandle) } 

这会产生一个错误fatal error: unexpectedly found nil while unwrapping an Optional value which stems from trying to call _createManager

我最终使用了这个解决方法:

 + (int) wifiStrength { UIApplication *app = [UIApplication sharedApplication]; NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews]; NSString *dataNetworkItemView = nil; for (id subview in subviews) { if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) { dataNetworkItemView = subview; break; } } return[[dataNetworkItemView valueForKey:@"wifiStrengthRaw"] intValue]; } 

没有任何权利或越狱的作品

由于iPhone X中的状态栏与其他iPhone不同,因此获取WiFi信息的方式也不同。

以下是如何通过“ 未记录的属性 ”获取它的解决方法,这意味着Apple可能会在未来不知情的情况下更改这些属性。 如果Apple更改了未记录的属性 ,应用程序将崩溃但我们没有相应地调整我们的代码。 所以我们必须在Swift中处理NSException。

创建一个Header文件,并将其添加到Bridging-Header.h中。 你可以在这里找到这个文件:https://gist.github.com/zhihuitang/6d3de0963d96a552d47721a598ca79c8

 // // OCCatch.h // // #ifndef OCCatch_h #define OCCatch_h // add the code below to your -Bridging-Header.h /** #import "OCCatch.h" */ // How to use it in Swift? /** let exception = tryBlock { let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView //...... } if let exception = exception { print("exception: \(exception)") } */ #import  NS_INLINE NSException * _Nullable tryBlock(void(^_Nonnull tryBlock)(void)) { @try { tryBlock(); } @catch (NSException *exception) { return exception; } return nil; } #endif /* OCCatch_h */ 

在iPhoneX中,我们可以获得WiFi的numberOfActiveBars ,范围从0到3.在除iPhoneX之外的其他iPhone中,我们可以获得WiFi RSSI。

在iPhoneX上,请使用getWiFiNumberOfActiveBars()

  private func getWiFiNumberOfActiveBars() -> Int? { let app = UIApplication.shared var numberOfActiveBars: Int? let exception = tryBlock { guard let containerBar = app.value(forKey: "statusBar") as? UIView else { return } guard let statusBarMorden = NSClassFromString("UIStatusBar_Modern"), containerBar .isKind(of: statusBarMorden), let statusBar = containerBar.value(forKey: "statusBar") as? UIView else { return } guard let foregroundView = statusBar.value(forKey: "foregroundView") as? UIView else { return } for view in foregroundView.subviews { for v in view.subviews { if let statusBarWifiSignalView = NSClassFromString("_UIStatusBarWifiSignalView"), v .isKind(of: statusBarWifiSignalView) { if let val = v.value(forKey: "numberOfActiveBars") as? Int { numberOfActiveBars = val break } } } if let _ = numberOfActiveBars { break } } } if let exception = exception { print("getWiFiNumberOfActiveBars exception: \(exception)") } return numberOfActiveBars } 

在iPhoneX以外的iPhone设备上,请使用getWiFiRSSI()

 private func getWiFiRSSI() -> Int? { let app = UIApplication.shared var rssi: Int? let exception = tryBlock { guard let statusBar = app.value(forKey: "statusBar") as? UIView else { return } if let statusBarMorden = NSClassFromString("UIStatusBar_Modern"), statusBar .isKind(of: statusBarMorden) { return } guard let foregroundView = statusBar.value(forKey: "foregroundView") as? UIView else { return } 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 } } } } if let exception = exception { print("getWiFiRSSI exception: \(exception)") } return rssi } 

到目前为止,我还没有找到在iPhoneX上获得WiFi RSSI的方法。 如果你们知道怎么做,请告诉我。 谢谢。

这是Github的演示项目

我认为最新版本的iOS不可能。 只有iOS4才有可能。

Apple不喜欢这种方法,并且威胁应用评论拒绝