user3732298
user3732298

Reputation: 123

Why can not I get UIStatusBarSignalStrengthItemView?

In order to obtain the wifi or cellular signal strength on iphone, I wrote the following code as reference for various sites, but it does not come in IF statement of "UIStatusBarSignalStrengthItemView" or "_UIStatusBarCellularSignalView".

Do you need permission?

■Development environment

Xcode9.4.1

iPhoneX iOS:11.0.1

■Test1.m

#import "Test1.h"
@implementation Test1 : NSObject 

- (int)antennaBar
{

    NSLog(@"%@",[[[UIApplication sharedApplication]     valueForKeyPath:@"statusBar"] subviews]);

    NSLog(@"antennaBar 1");
    NSLog(@"antennaBar 2");
//    NSArray *subviews = [[[apps valueForKey:@"statusBar"]     valueForKey:@"foregroundView"] subviews];
    NSArray *subviews = nil;
    NSLog(@"antennaBar 3");
    id statusBar = [[UIApplication sharedApplication] valueForKey:@"statusBar"];
    NSLog(@"antennaBar 4");
    if ([statusBar isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) {
        NSLog(@"antennaBar 5");
    subviews = [[[statusBar valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
} else {
    NSLog(@"antennaBar 6");
    subviews = [[statusBar valueForKey:@"foregroundView"] subviews];
}
NSLog(@"antennaBar 7");
NSString *dataNetworkItemView = nil;

NSLog(@"antennaBar 8");
for (id subview in subviews) {

    NSLog(@"Class - %@", NSStringFromClass([subview class]));

    NSLog(@"antennaBar aaaaaaa");
    if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarSignalStrengthItemView") class]]) {
        NSLog(@"antennaBar bbbbbb");
        dataNetworkItemView = subview;
        break;
    }
    if([subview isKindOfClass:[NSClassFromString(@"_UIStatusBarCellularSignalView") class]]) {
        NSLog(@"antennaBar eeeeee");
        dataNetworkItemView = subview;

        int fffff = [subview valueForKey:@"numberOfActiveBars"];
        NSLog(@"fffff=%d",fffff);
        break;
    }
}

for (id subview in subviews)
{
    NSLog(@"antennaBar cccccc");
    if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]])
    {
        NSLog(@"antennaBar dddddd");
        [(NSNumber*)[subview valueForKey:@"dataNetworkType"] intValue];
    }
}

NSLog(@"antennaBar 9");


NSLog(@"12345");
id statusBaraaaa = [[UIApplication sharedApplication] valueForKey:@"statusBar"];
NSArray *children = nil;
NSLog(@"23456");
children = [[[statusBaraaaa valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
NSLog(@"34567");
int type = 0;
NSLog(@"45678");
for (id child in children) {
    NSLog(@"56789");
    if ([child isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) {
        NSLog(@"67890");
        type = [[child valueForKeyPath:@"dataNetworkType"] intValue];
    }
}

if (type == 0) {
    return NO;
}else{
    return YES;
}

int aaa = [[dataNetworkItemView valueForKey:@"signalStrengthBars"] intValue];


NSLog(@"aaa=%d",aaa);

return aaa;
}

@end

■Test1.h

#import <Foundation/Foundation.h>
#import "UIKit/UIKit.h"

@interface Test1 : NSObject
- (int)antennaBar;
@end

■Log OutPut

( "<_UIStatusBar: 0x14e809020: regions={\n bottomLeading = \"<_UIStatusBarRegion: 0x1d013bd00: identifier=bottomLeading, enabled=1, displayItems={(\n)}>\";\n expandedLeading = \"<_UIStatusBarRegion: 0x1d013bbc0: identifier=expandedLeading, enabled=0, displayItems={(\n)}>\";\n expandedTrailing = \"<_UIStatusBarRegion: 0x1d013bc60: identifier=expandedTrailing, enabled=0, displayItems={(\n)}>\";\n leading = \"<_UIStatusBarRegion: 0x1d013b940: identifier=leading, enabled=1, displayItems={(\n <_UIStatusBarDisplayItem: 0x1d019b450: identifier=_UIStatusBarTimeItem.shortTimeDisplayIdentifier, item=<_UIStatusBarTimeItem: 0x1d046c700: identifier=_UIStatusBarTimeItem>, view=<_UIStatusBarStringView: 0x14e825ae0; frame = (14.3333 3.66667; 38.3333 18); text = '12:10'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x1d0281f40>>>\n)}>\";\n pill = \"<_UIStatusBarRegion: 0x1d013b8a0: identifier=pill, enabled=0, displayItems={(\n)}>\";\n systemUpdates = \"<_UIStatusBarRegion: 0x1d0

1

2

3

4

5

7

8

Class - UIView

aaaaaaa

Class - UIView

aaaaaaa

Class - UIView

aaaaaaa

Class - UIView

aaaaaaa

Class - UIView

aaaaaaa

Class - UIView

aaaaaaa

cccccc

cccccc

cccccc

cccccc

cccccc

cccccc

9

12345

23456

34567

45678

56789

56789

56789

56789

56789

56789

Upvotes: 0

Views: 934

Answers (2)

i0s_tweak3r
i0s_tweak3r

Reputation: 26

You can retrieve the number of bars that are active, how many are possible, and whether the user is connected to wifi or cellular. (I believe that's what the "mode" property/ iVar is for.)

I've used the inactive and activeColor methods to set the colors of wifi and cellular data based on strength of signal, without using number of active bars, because it's visually represented. Of course I'm on a jailbroken device and made it as a tweak, and using this API without hiding it well can get your app rejected. BUT anyways, try out _UIStatusBarSignalView to get the info you need (for testing purposes only of course). I think this only works on Modern status bars / iPhone X type's.

    @interface _UIStatusBarSignalView : UIView <_UIStatusBarDisplayable> {
BOOL _smallSize;
BOOL _visible;
long long _numberOfBars;
long long _numberOfActiveBars;
long long _signalMode;
UIColor* _inactiveColor;
UIColor* _activeColor;

 }

 @property (assign,nonatomic) long long numberOfBars;                                                            
 //@synthesize numberOfBars=_numberOfBars - In the implementation block
 @property (assign,nonatomic) long long numberOfActiveBars; 
/* You can use this compared to the output of numberOfBars property to get a     
good idea of signal strength. */
//@synthesize numberOfActiveBars=_numberOfActiveBars - In the implementation    
//block
@property (assign,nonatomic) long long signalMode;  
 //...(more to the interface)
@end  

The full interface can be found here, and I can confirm it works on iOS 12.4 for iPhone X, even though the class dump is from 11.1.2. http://developer.limneos.net/?ios=11.1.2&framework=UIKit.framework&header=_UIStatusBarSignalView.h

Upvotes: 0

guru_meditator
guru_meditator

Reputation: 549

While getting the signal strength by inspecting the status bar view hierarchy worked in some previous versions of iOS, that no longer works as of iOS 11. Also, relying on internal views is (and has always been) ground for rejection in the app store review process.

There is no supported way to get the cellular signal strength. Source: comment on Apple Developer Forum. The only supported way to get the WiFi signal strength is using the NEHotspotNetwork signalStrength property. But this property is only available to hotspot helper apps, and requires a special entitlement.

Upvotes: 2

Related Questions