Reputation: 123
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
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
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