这个问题坑了很久了,终于搞定了 —。—|||
如果使用CoreTelephony.framework 框架,获取的仅仅是Sim卡的运营商(而且还不成功!carrier.name属性为Carrier,坑死人了!)
那么思路稍微转一下,当手机漫游的时候,会接入当地的运营商,在手机Status Bar上会显示出来,那么只要获得Status Bar上显示的名字即可获得漫游手机接入网络的运营商了。
(1)进入Rumtime模式
#import <objc/message.h>
(2)进入实现代码:
要知道最终获取到状态栏上的运营商名称要经过一层层的提取,下面就开始一层层分析
1. 获得标题栏并遍历其中的所有元素
//状态栏是由当前app控制的,首先获取当前app
UIApplication *app = [UIApplicationsharedApplication];
id statusBar = [app valueForKeyPath:@"statusBar"];
// 遍历状态栏的所有成员
unsigned int outCount =0;
Ivar *ivars = class_copyIvarList([statusBarclass], &outCount);
for (int i =0; i < outCount; i++) {
Ivar ivar = ivars[i];
printf("%s\n",ivar_getName(ivar));
}
打印出的元素有:
_styleDelegate
_statusBarWindow
_statusBarServer
_showsForeground
_backgroundView
_foregroundView
_doubleHeightLabel
_currentDoubleHeightText
_currentRawData
_interruptedAnimationCompositeViews
_newStyleBackgroundView
_newStyleForegroundView
_slidingStatusBar
_requestedStyle
_styleOverrides
_style
_orientation
_hidden
_suppressesHiddenSideEffects
_foreground
_registered
_styleRequestedWhileHidden
_waitingOnCallbackAfterChangingStyleOverridesLocally
_suppressGlow
_translucentBackgroundAlpha
_showOnlyCenterItems
_localDataOverrides
_tintColor
_lastUsedTintColor
_nextTintTransition
2. 进入foregroundView元素并遍历其所有子元素
NSArray *children = [[[appvalueForKeyPath:@"statusBar"]valueForKeyPath:@"foregroundView"]subviews];
for (id childin children) {
NSLog(@"%@", [childclass]);
}
打印结果如下:
UIStatusBarSignalStrengthItemView
UIStatusBarServiceItemView
UIStatusBarDataNetworkItemView
UIStatusBarBatteryItemView
UIStatusBarBatteryPercentItemView
UIStatusBarTimeItemView
3. 进入UIStatusBarServiceItemView元素并遍历其所有子元素
NSArray *children = [[[appvalueForKeyPath:@"statusBar"]valueForKeyPath:@"foregroundView"]subviews];
for (id childin children) {
if ([childisKindOfClass:NSClassFromString(@"UIStatusBarServiceItemView")]) {
unsigned int outCount =0;
Ivar *ivars = class_copyIvarList([childclass], &outCount);
for (int i =0; i < outCount; i++) {
Ivar ivar = ivars[i];
printf("%s\n",ivar_getName(ivar));
}
}
}
打印结果如下:
_pathToServiceImages
_serviceString
_crossfadeString
_crossfadeStep
_maxWidth
_serviceWidth
_crossfadeWidth
_contentType
_loopingNecessaryForString
_usingStringForStyle
_loopNowIfNecessary
_letterSpacing
4. 通过serviceString获取运营商名称
NSArray *children = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
for (id child in children) {
if ([child isKindOfClass:NSClassFromString(@"UIStatusBarServiceItemView")]) {
// 遍历当前状态栏的所有属性,找到关于状态栏的
id type = [child valueForKeyPath:@"serviceString"];
NSLog(@"carrier is %@", type);
break;
}
}
打印结果:
carrier is 中国联通
总结一下,获取标题栏上的运营商的名称主要过程为:
statusBar -> foregroundView -> UIStatusBarServiceItemView -> serviceString -> 运营商名字
最后贴一下代码供大家参考
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 状态栏是由当前app控制的,首先获取当前app
UIApplication *app = [UIApplication sharedApplication];
NSArray *children = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
for (id child in children) {
if ([child isKindOfClass:NSClassFromString(@"UIStatusBarServiceItemView")]) {
id type = [child valueForKeyPath:@"serviceString"];
NSLog(@"carrier is %@", type);
break;
}
}
return YES;
}