有没有办法以编程方式了解 iPhone 上的手机运营商?
我正在寻找 iPhone 连接的运营商名称。
在 iOS 4 中,CoreTelephony 框架是可用的,这是获取运营商名称的片段:
CTTelephonyNetworkInfo *netinfo = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier *carrier = [netinfo subscriberCellularProvider];
NSLog(@"Carrier Name: %@", [carrier carrierName]);
[netinfo release];
链接到 CoreTelephony 并包含在您的标题中:
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
只是在这里做个说明..我在不同的 SIM 上测试了这个 API,似乎 iPhone 锁定的运营商的名称返回了 [carrer carrierName]!
我在 2 部 iPhone 上进行了测试,一部被锁定,另一部未锁定,对于锁定的一部,无论 SIM 提供商如何,它都会在我每次运行我的测试应用程序时返回它被锁定的运营商的名称。但是请注意,跨国公司确实发生了变化!
对于 swift 用户,您可以尝试以下操作:
import CoreTelephony
static var carrierName:String? {
let networkInfo = CTTelephonyNetworkInfo()
let carrier = networkInfo.subscriberCellularProvider
return carrier?.carrierName
}
没有用于获取运营商名称的公共 API。如果您不需要在 App Store 上发布,您可以考虑使用私有 api。
VVCarrierParameters.h
在 VisualVoiceMail 包中似乎有一个carrierServiceName
可能是您需要的类方法。将该标题放在您的项目中并调用[VVCarrierParameters carrierServiceName]
.
请注意,如果您这样做,您的应用很可能会被拒绝。
在开发Alpha时,我遇到了同样的问题。该项目本身不仅限于使用公共 API,所以首先我尝试了 @Jason Harwig 的解决方案。因为我无法让它工作,我想到了另一种选择。
我的解决方案使用私有 API 来访问状态栏中显示_serviceString
的标签 ( ) 的 ivar 。UIStatusBarServiceItemView
它依赖于具有载体值的状态栏,只需要UIKit
工作。
- (NSString *)carrierName
{
UIView* statusBar = [self statusBar];
UIView* statusBarForegroundView = nil;
for (UIView* view in statusBar.subviews)
{
if ([view isKindOfClass:NSClassFromString(@"UIStatusBarForegroundView")])
{
statusBarForegroundView = view;
break;
}
}
UIView* statusBarServiceItem = nil;
for (UIView* view in statusBarForegroundView.subviews)
{
if ([view isKindOfClass:NSClassFromString(@"UIStatusBarServiceItemView")])
{
statusBarServiceItem = view;
break;
}
}
if (statusBarServiceItem)
{
id value = [statusBarServiceItem valueForKey:@"_serviceString"];
if ([value isKindOfClass:[NSString class]])
{
return (NSString *)value;
}
}
return @"Unavailable";
}
- (UIView *)statusBar
{
NSString *statusBarString = [NSString stringWithFormat:@"%@ar", @"_statusB"];
return [[UIApplication sharedApplication] valueForKey:statusBarString];
}
我只使用状态栏可见的应用程序测试了该方法。它返回与状态栏中显示的字符串相同的字符串,因此即使在漫游时也能正常工作。
这种方法不是 App Store 安全的。
如果 Core Telephony 返回“运营商”,则从状态栏中获取运营商名称
func getCarrierName() -> String? {
var carrierName: String?
let typeName: (Any) -> String = { String(describing: type(of: $0)) }
let statusBar = UIApplication.shared.value(forKey: "_statusBar") as! UIView
for statusBarForegroundView in statusBar.subviews {
if typeName(statusBarForegroundView) == "UIStatusBarForegroundView" {
for statusBarItem in statusBarForegroundView.subviews {
if typeName(statusBarItem) == "UIStatusBarServiceItemView" {
carrierName = (statusBarItem.value(forKey: "_serviceString") as! String)
}
}
}
}
return carrierName
}
对于 Swift 和 ios 12.0 < 执行以下操作:
导入核心电话
static var carrierName:String? {
CTTelephonyNetworkInfo().serviceSubscriberCellularProviders?.first?.value.carrierName ?? ""
}
有这样一种方式,但它仅在 iOS 4 上可用,因此您将无法在以前的版本上使用它。这也可能会破坏您的向后兼容性。
当您打印运营商的输出时?.description
这是你看到的:
[\"0000000100000001\": CTCarrier (0x2803a1980) {\n\t运营商名称:[Vodafone]\n\t移动国家代码:[214]\n\t移动网络代码:[01]\n\tISO国家代码:[es ]\n\t允许 VOIP?[是]\n}\n]
格式化(\n 和 \t):
[\"0000000100000001\": CTCarrier (0x2803a1980) {
Carrier name: [Vodafone]
Mobile Country Code: [214]
Mobile Network Code:[01]
ISO Country Code:[es]
Allows VOIP? [YES]
}
]
所以从状态栏中获取运营商名称是一个不错的选择(至少对我来说)
我的意思是“codethemall”用户的回答。
更重要的评论。只需添加有关以下内容的文档carrierName
:
运营商提供此字符串,对其进行格式化以呈现给用户。如果用户正在漫游,该值不会改变;它始终代表用户拥有帐户的提供商。
如果您为运营商配置设备,然后移除SIM 卡,此属性将保留运营商的名称。如果您随后安装 新SIM 卡,其运营商名称将替换此属性的先前值。
如果用户从未为设备配置运营商,则此属性的值为 nil 。