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

问题描述 投票:44回答:8

有没有办法以编程方式知道iPhone上的手机载体?

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

iphone cocoa-touch core-telephony
8个回答
81
投票

在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>

13
投票

只是在这里做一个注释..我在不同的SIM上测试了这个API,似乎iPhone锁定的操作符的名称是[carrer carrierName]返回的!

我在2个iphone上测试了这个,一个是锁定的,另一个没有,而对于锁定的,无论SIM提供商,它都会返回每次运行我的测试应用时锁定的操作员的名称。但请注意,MNC确实发生了变化!


2
投票

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

VisualVoiceMail包中的VVCarrierParameters.h似乎有一个carrierServiceName类方法,可能就是你需要的。删除项目中的标题并调用[VVCarrierParameters carrierServiceName]

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


2
投票

如果Core Telephony返回“Carrier”,请从状态栏中获取运营商名称

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
}

1
投票

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

我的解决方案使用私有API访问状态栏中显示的标签(_serviceString)的UIStatusBarServiceItemView 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的安全。


0
投票

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

有这样的方式,但它只在iOS 4上可用,所以你将无法在以前的版本上使用它。这也可能会破坏你的向后兼容性。


0
投票

对于快速用户,您可以尝试这样做:

import CoreTelephony

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

0
投票

当您打印载体的输出?.description

这就是你看到的:

[\“0000000100000001 \”:CTCarrier(0x2803a1980){\ n \ tCarrier名称:[Vodafone] \ n \ t移动国家代码:[214] \ n \ t移动网络代码:[01] \ n \ tISO国家代码:[es ] \ n \ t允许VOIP? [YES] \ 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”用户的答案。

© www.soinside.com 2019 - 2024. All rights reserved.