Home > OS >  Calculating Wi-Fi strength problematically
Calculating Wi-Fi strength problematically

Time:05-05

I want to get the device Wi-Fi strength, but found no straightforward way to accomplish this

Right now I have this which used to work before iOS 13 however now I get this crash.

func wifiStrength() -> Double {
    let app = UIApplication.shared
    let subviews = ((app.value(forKey: "statusBar") as! NSObject).value(forKey: "foregroundView") as! UIView).subviews
    var dataNetworkItemView: UIView?

    for subview in subviews {
        if subview.isKind(of: NSClassFromString("UIStatusBarDataNetworkItemView")!) {
            dataNetworkItemView = subview
            break
        }
    }

    let dBm = (dataNetworkItemView!.value(forKey: "wifiStrengthRaw") as! NSNumber).intValue
    var strength = (Double(dBm)   90.0) / 60.0
    if strength > 1 {
        strength = 1
    }
    return strength
}

The crash error message.

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'App called -statusBar or -statusBarWindow on UIApplication: this code must be changed as there's no longer a status bar or status bar window. Use the statusBarManager object on the window scene instead.'

terminating with uncaught exception of type NSException

Does anyone know how to adapt the previous approach on iOS 13? Or of a different way to gather Wi-Fi signal strength.

CodePudding user response:

There is no way to get wifi strength on an iOS application. Please see this thread in Apple Developer Forums: https://developer.apple.com/forums/thread/107046?answerId=325726022#325726022

there is no supported way for general apps to get Wi-Fi signal strength on iOS

Rooting around internal / private structures using value(forKey:) is unsupported, unstable, and could get your app rejected from the app store.

CodePudding user response:

I solve the problem this is the updated code which works on iOS 15

    func wifiStrength() -> Double {
        let statusBarManager = UIApplication.shared
            .keyWindow?
            .windowScene?
            .statusBarManager
        let hascreateLocalStatusBar = statusBarManager?
            .responds(to: Selector("createLocalStatusBar"))
        
        if !(hascreateLocalStatusBar ?? false) {
            return -1
        }
        
        guard let createLocalStatusBar = statusBarManager?
            .perform(Selector("createLocalStatusBar"))
            .takeUnretainedValue() as?
            UIView else { print("not UIVirw"); return 0};

        let hasStatusBar = createLocalStatusBar.responds(to:  Selector("statusBar"))
        if !hasStatusBar {
            return -1
        }
        
        let statusBar = (createLocalStatusBar.perform(Selector("statusBar"))
            .takeUnretainedValue() as! UIView)
            
    
        guard let value = (((statusBar.value(forKey: "_statusBar") as? NSObject)?
            .value(forKey: "_currentAggregatedData") as? NSObject)?
            .value(forKey: "_wifiEntry") as? NSObject)?
            .value(forKey: "_rawValue") else { return -1}
                
        print("           
  • Related