0

Disclaimer: Ignore the fact that a production app using this may or may not pass review. I'm just trying to get this concept to work. Here's the code I'm trying to execute, all I'm trying to do (for now) is initialize four constants and it has difficulty on the third.

let app = UIApplication.shared
let statusBar = app.value(forKey: "statusBar") as AnyObject
let foregroundView = statusBar.value(forKey: "foregroundView") as AnyObject
let subviews = Array(foregroundView.subviews)

The error is given:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<_SwiftValue 0x170087850> valueForUndefinedKey:]: this class is not key value coding-compliant for the key foregroundView.'

Note that, unlike most other key value compliancy error that occur when the app is ran, mine only occurs when executing the IBAction (triggered by UIButton) that has the four line of code in it.

For reference, I'm trying to achieve what this post describes in Objective-C. I'm new to Swift but I think I translated it properly.

The entire func is here:

@IBAction func getSignal(_ sender: UIButton) {

    let app = UIApplication.shared
    let statusBar = app.value(forKey: "statusBar") as AnyObject
    let foregroundView = statusBar.value(forKey: "foregroundView") as AnyObject
    let subviews = Array(foregroundView.subviews)
    var dataNetworkItemView: UIView?
    for subview in subviews {
        if (subview as AnyObject).isKind(of: NSClassFromString("UIStatusBarSignalStrengthItemView")!) {
            dataNetworkItemView = subview
            break
        }
    }
    let signalStrength = (dataNetworkItemView?.value(forKey: "signalStrengthRaw") as? NSString)?.intValue
    print("signal \(signalStrength)")
}

which I converted from the block of original code, here:

    UIApplication *app = [UIApplication sharedApplication];
    NSArray *subviews = [[[app valueForKey:@"statusBar"]     valueForKey:@"foregroundView"] subviews];
    NSString *dataNetworkItemView = nil;
    for (id subview in subviews) {
        if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarSignalStrengthItemView") class]])
        {
            dataNetworkItemView = subview;
            break;
        }
    }
    int signalStrength = [[dataNetworkItemView valueForKey:@"signalStrengthRaw"] intValue];
    NSLog(@"signal %d", signalStrength);

There are no compile-time errors or warnings, and I'm at a loss for how to continue. Thanks.

Community
  • 1
  • 1
willbattel
  • 1,040
  • 1
  • 10
  • 37

1 Answers1

1

Working Xcode 8 beta, Swift 3.0 Code:

let app = UIApplication.shared
let statusBar = app().value(forKey: "statusBar")! as AnyObject
let foregroundView = statusBar.value(forKey: "foregroundView")! as AnyObject
let subviews = Array(foregroundView.subviews)
var dataNetworkItemView: UIView?
for subview in subviews {
    if (subview as AnyObject).isKind(of: NSClassFromString("UIStatusBarSignalStrengthItemView")!) {
        dataNetworkItemView = subview
        break
    }
}
let signalStrength = (dataNetworkItemView?.value(forKey: "signalStrengthRaw") as? NSString)?.intValue
print("signal \(signalStrength)")

The OP is using Xcode 8 GM, hence one change- app() to app:

let statusBar = app.value(forKey: "statusBar")! as AnyObject
Bista
  • 7,869
  • 3
  • 27
  • 55
  • I like the idea, this is a better method. The error I get with this is compile time, on the second line, "Value of type '[String : AnyObject]' has no member 'value'" – willbattel Sep 17 '16 at 04:53
  • Yes, I updated to Xcode 8 and started this project in Swift 3 about an hour ago. – willbattel Sep 17 '16 at 05:04
  • This worked syntactically (but I had to remove the parentheses after "app" on the second line to remove a compile-time error), and therefore technically solved my original problem, so I'll mark it as the answer. I do have a followup question however if you can suggest anything. The printed message says "signal nil", so I put a print test message in the if statement in the loop, and that does get triggered. So do you think the nil is coming from the declaration of signalStrength? I copied this key value from another post that supposedly had it working so it's strange to me that it doesn't work. – willbattel Sep 17 '16 at 05:19
  • You have to remove parenthesis because I am using Xcode 8 beta version. For the followup - Are you using real device? – Bista Sep 17 '16 at 05:21
  • Yes, according to the author of that other linked post it won't work on the simulator, which makes sense given there is no actual cell service in the simulator. I'm running in iOS 10 on my iPhone. – willbattel Sep 17 '16 at 05:25
  • `nil` is coming from `let signalStrength = (dataNetworkItem...` line, I think the code is compiling, but there is some changes in the in-build methods. I do not have iOS10 running real device. :( – Bista Sep 17 '16 at 05:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/123577/discussion-between-willb-and-mr-ub). – willbattel Sep 17 '16 at 05:34