问题
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