swift 使用私有API读取WiFi RSSI值

nbnkbykc  于 2023-09-29  发布在  Swift
关注(0)|答案(5)|浏览(129)

我正在做一些不需要在App store上发布的东西,所以我可以使用私有API来满足我的需求,我试图使用MobileWiFi. framework to read the RSSI value for the wireless network the phone is currently connected to. I've included thehttps://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

xytpbqjk

xytpbqjk1#

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

+ (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];
}

工作没有任何权利或越狱

nuypyhwy

nuypyhwy2#

由于iPhone X中的状态栏与其他iPhone不同,因此获取WiFi信息的方式也不同。
以下是如何通过“未记录的属性”获得它的解决方案,这意味着Apple可能会在未来更改这些属性而不让我们知道。如果Apple更改了未记录的属性,应用程序将崩溃,但我们没有相应地调整代码。所以我们必须在Swift中处理NSException。
创建一个头文件,并将其添加到Bridging-Header.h中。您可以找到文件here: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 <Foundation/Foundation.h>

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 nil }
        guard let statusBarMorden = NSClassFromString("UIStatusBar_Modern"), containerBar .isKind(of: statusBarMorden), let statusBar = containerBar.value(forKey: "statusBar") as? UIView else { return nil }

        guard let foregroundView = statusBar.value(forKey: "foregroundView") as? UIView else { return nil }

        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上获取WiFiRSSI的方法。如果你们知道怎么做,也请告诉我。谢谢.
下面是Github中的demo project

mnowg1ta

mnowg1ta3#

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

k7fdbhmy

k7fdbhmy4#

Apple不喜欢这种方式,并威胁app review rejection

toiithl6

toiithl65#

rssi and other stats
iOS 17开放了Wi-Fi API,可以在无线测试中使用。
为了使用它:
升级到ios 17下载快捷方式https://www.icloud.com/shortcuts/f4aa1682c2b241bd838bf60dba0a3bae

相关问题