A way to calculate or get wifi strength on Swift on iOS 11

↘锁芯ラ 提交于 2019-12-11 05:26:46

问题


Looking for a way to either get or calculate the wifi strength of a device? Have seen examples of scraping the status bar but cannot get it to work on iOS 11:

func getSignalStrength() -> Int {
    let application = UIApplication.shared
    let statusBarView = application.value(forKey: "statusBar") as! UIView
    let foregroundView = statusBarView.value(forKey: "foregroundView") as! UIView
    let foregroundViewSubviews = foregroundView.subviews

    var dataNetworkItemView:UIView!

    for subview in foregroundViewSubviews {
        if subview.isKind(of: NSClassFromString("UIStatusBarSignalStrengthItemView")!) {
            dataNetworkItemView = subview
            print("NONE")
            break
        } else {
            print("NONE")

            return 0 //NO SERVICE
        }
    }

    return dataNetworkItemView.value(forKey: "signalStrengthBars") as! Int
}

Any clever ideas?

Does not need to be approved by apple


回答1:


The code you have is for the mobile network(2G/3G/4G etc), not for WiFi network.

Try the code below in Swift4, it works on my iOS11:

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 {
                //print("rssi: \(val)")

                rssi = val
                break
            }
        }
    }
    return rssi
}

How to get the WiFi strength on iPhoneX, check my answer in another post: Using Private API To read WiFi RSSI Value




回答2:


You can use this code of every device include all new iphones

class DeviceType {

static let deviceType = UIDevice.current.modelName
class func getDevice() -> Devices{
    switch deviceType {
    case "iPhone10,3", "iPhone10,6":
        print("iPhoneX")
        return Devices.iPhoneX
    case "iPhone11,2":
        print("iPhone XS")
        return Devices.iPhoneXS
    case "iPhone11,4":
        print("iPhone XS Max")
        return Devices.iPhoneXSMax
    case "iPhone11,6":
        print("iPhone XS Max China")
        return Devices.iPhoneXSMaxChina
    case "iPhone11,8":
        print("iPhone XR")
        return Devices.iPhoneXR
    default:
        return Devices.none
    }
}

}

extension UIDevice {
    var modelName: String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        let identifier = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8, value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }
        return identifier
    }
}


enum Devices {
    case iPhoneX
    case iPhoneXS
    case iPhoneXSMax
    case iPhoneXSMaxChina
    case iPhoneXR
    case none
}

func getSignalStrength() -> Int {


var classNameForStatusBar = ""
var valueForSignalValue = ""

classNameForStatusBar = "UIStatusBarSignalStrengthItemView"
valueForSignalValue = "signalStrengthBars"

let app = UIApplication.shared
let statusBarView = app.value(forKey: "statusBar") as! UIView
if UIDevice().userInterfaceIdiom == .phone {
    switch UIScreen.main.nativeBounds.height {
    case 2436, 2688, 1792:
        print("iPhone X, XS")
        return checkStatus(statusBarView)
    default:
        if(statusBarView.frame.width == 1024.0 ||  statusBarView.frame.width == 1112.0 || statusBarView.frame.width == 1024.0 || statusBarView.frame.width == 768.0){
            if let viewStatus = statusBarView.value(forKey: "statusBar") as? UIView{
                if let foregroundView = viewStatus.value(forKey: "foregroundView") as? UIView{
                    let subViews = foregroundView.subviews
                    var dataNetworkItemView:UIView?
                    for subview in subViews {

                        if subview.isKind(of: NSClassFromString(classNameForStatusBar)!){
                            dataNetworkItemView = subview;
                            break
                        }
                    }
                    guard let signal = dataNetworkItemView?.value(forKey: valueForSignalValue) as? Int else { return 0 }
                    return signal
                }
            }
            return 0
        }
        print("Unknown")
        if let foregroundView = statusBarView.value(forKey: "foregroundView") as? UIView{
            let subViews = foregroundView.subviews

            var dataNetworkItemView:UIView?
            for subview in subViews {

                if subview.isKind(of: NSClassFromString(classNameForStatusBar)!){
                    dataNetworkItemView = subview;
                    break
                }
            }
            guard let signal = dataNetworkItemView?.value(forKey: valueForSignalValue) as? Int else { return 0 }
            return signal
        }
    }
}
return 0

}

private func checkStatus(_ statusBarView: UIView) -> Int{
    if DeviceType.getDevice() == .iPhoneX{
        if let viewStatus = statusBarView.value(forKey: "statusBar") as? UIView{
            if let foregroundView = viewStatus.value(forKey: "foregroundView") as? UIView{
                let subViews = foregroundView.subviews
                var dataNetworkItemView:UIView?
                for subview in subViews {
                    for localSubView in subview.subviews{
                        if localSubView.isKind(of: NSClassFromString("_UIStatusBarCellularSignalView")!){
                            dataNetworkItemView = localSubView
                            break
                        }
                    }
                }
                if dataNetworkItemView == nil{
                    return 0
                }else{
                    return 1
                }
//                guard let signal = dataNetworkItemView?.value(forKey: "signalStrengthBars") as? Int else { return 0 }
//                return signal
            }
        }
    }else{
        if let viewStatus = statusBarView.value(forKey: "statusBar") as? UIView{
            if let foregroundView = viewStatus.value(forKey: "foregroundView") as? UIView{
                let subViews = foregroundView.subviews
                var dataNetworkItemView:UIView?
                print(foregroundView)
                print(viewStatus)
                print(statusBarView)
                for subview in subViews {
                    for localSubview in subview.subviews{
                        if localSubview.isKind(of: NSClassFromString("_UIStatusBarDualCellularSignalView")!){
                            dataNetworkItemView = subview;
                            break
                        }else if localSubview.isKind(of: NSClassFromString("_UIStatusBarCellularSignalView")!){
                            print("Check this")
                        }
                    }
                }
                if dataNetworkItemView == nil{
                    return 0
                }else{
                    return 1
                }
            }
        }
    }
    return 0
}

Just copy paste this code in any swift file.



来源:https://stackoverflow.com/questions/47564350/a-way-to-calculate-or-get-wifi-strength-on-swift-on-ios-11

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!