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

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

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

【问题讨论】:

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

标签: ios networking core-telephony carrier


【解决方案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 卡,它的运营商名称替换了之前的值 属性。

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-04-03
              • 2010-11-19
              • 2012-08-01
              • 2017-02-20
              • 2012-12-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多