以编程方式从 iPhone 检索运营商名称

Posted

技术标签:

【中文标题】以编程方式从 iPhone 检索运营商名称【英文标题】:Retrieving Carrier Name from iPhone programmatically 【发布时间】:2010-10-25 14:31:30 【问题描述】:

有没有办法以编程方式了解 iPhone 上的手机运营商?

我正在寻找 iPhone 连接的运营商名称。

【问题讨论】:

什么,你的意思是除了 AT&T 之外还有 iPhone 运营商? 您是在谈论手机当前连接到谁的服务(即可能正在漫游),还是您从谁那里获得账单? 你可能没听说过,但世界上还有其他国家。有趣的是,他们确实拥有移动技术。 再次 - 有幽默感的人。 检测您是否在漫游的唯一机制是通过读取未记录的系统文件See previous question,这违反了 Apple 规则 【参考方案1】:

ios 4 中,CoreTelephony 框架是可用的,这里有一个 sn-p 来获取运营商名称:

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>

【讨论】:

根据 Apple 的文档,这始终为您提供有关您的 honme 运营商的信息,而不是您在漫游时当前连接的运营商。 对于运营商名称,它只是“运营商”,而不是类似于 verizon,...。【参考方案2】:

只是在这里做个说明。我在不同的 SIM 卡上测试了这个 API,似乎 iPhone 锁定的运营商名称返回了 [carrer carrierName]!!

我在 2 部 iPhone 上对此进行了测试,一部已锁定,另一部未锁定,对于已锁定的一部,无论 SIM 提供商如何,它都会在我每次运行我的测试应用程序时返回锁定的运营商名称。但是请注意,跨国公司确实发生了变化!

【讨论】:

好评。直到我看到这个回复才意识到这一点。可以确认我得到了相同的行为 - 运营商名称返回锁定的运营商名称,而不是 SIM 运营商。 在 iOS 7 上测试,解锁手机:始终返回“运营商”作为运营商名称。因此无法正确判断电话中是哪个运营商。返回的字符串等于设置 -> 常规 -> 关于运营商下显示的字符串。但是,版本号丢失了。 这是正确的。 MNC 是 CTCarrier 唯一准确的运营商测试。我们也会缓存 MNC 值,因为如果用户没有网络连接、处于飞行模式或移除了他们的 SIM,它将返回 nil。【参考方案3】:

对于 swift 用户,你可以试试这个:

import CoreTelephony

static var carrierName:String? 
    let networkInfo = CTTelephonyNetworkInfo()
    let carrier = networkInfo.subscriberCellularProvider
    return carrier?.carrierName

【讨论】:

carrier?.carrierName 目前不存在 当前存在运营商?.description 运营商的输出?.description: [\"0000000100000001\": CTCarrier (0x2803a1980) \n\t运营商名称: [Vodafone]\n\t手机国家代码: [214]\n\ t移动网络代码:[01]\n\tISO 国家代码:[es]\n\t允许 VOIP? [是]\n\n]【参考方案4】:

没有用于获取运营商名称的公共 API。如果您不需要在 App Store 上发布,您可以考虑使用私有 api。

VisualVoiceMail 包中的VVCarrierParameters.h 似乎有一个carrierServiceName 类方法,这可能是您需要的。将该标题放在您的项目中并调用[VVCarrierParameters carrierServiceName]

请注意,如果您这样做,您的应用很可能会被拒绝

【讨论】:

【参考方案5】:

在开发Alpha 时,我遇到了同样的问题。该项目本身不仅限于使用公共 API,所以首先我尝试了 @Jason Harwig 的解决方案。因为我无法让它工作,我想到了另一种选择。

我的解决方案使用私有 API 来访问状态栏中显示的标签 (UIStatusBarServiceItemView) 的 _serviceString ivar。

它依赖于状态栏有一个载体值,只需要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 安全的。

【讨论】:

【参考方案6】:

如果 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

【讨论】:

这种方法App Store安全吗?【参考方案7】:

对于 Swift 和 ios 12.0

导入 CoreTelephony

static var carrierName:String? 
    CTTelephonyNetworkInfo().serviceSubscriberCellularProviders?.first?.value.carrierName ?? ""

【讨论】:

【参考方案8】:

https://developer.apple.com/iphone/prerelease/library/documentation/NetworkingInternet/Reference/CTCarrier/Reference/Reference.html#//apple_ref/doc/uid/TP40009596-CH1-DontLinkElementID_3

有这样一种方式,但它仅适用于 iOS 4,因此您将无法在以前的版本中使用它。这也可能会破坏您的向后兼容性。

【讨论】:

【参考方案9】:

当您打印运营商的输出时?.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”用户的回答。

【讨论】:

【参考方案10】:

更多重要评论。只需添加docs 关于carrierName

运营商提供此字符串,并将其格式化以呈现给 用户。如果用户漫游,该值不会改变;它总是 表示用户拥有帐户的提供商。

如果您为运营商配置设备,然后移除 SIM 卡, 此属性保留承运人的名称。如果你然后安装一个 SIM 卡,它的运营商名称替换了之前的值 属性。

如果用户从不配置了一个 设备的载体。

【讨论】:

以上是关于以编程方式从 iPhone 检索运营商名称的主要内容,如果未能解决你的问题,请参考以下文章

无法检索运营商名称

以编程方式获取网络运营商的时间(android)

iPhone修改手机运营商名称,不越狱1分钟搞定

以编程方式检索 iPhone 上的内存使用情况

如何以编程方式在 Android(KitKat 及更高版本)中添加 APN

我们可以以编程方式更改在 iPhone 中创建的快捷方式的图标和名称吗