Есть ли способ узнать сотовый оператор на iPhone программно?
Я ищу имя оператора, к которому подключен iPhone.
Есть ли способ узнать сотовый оператор на iPhone программно?
Я ищу имя оператора, к которому подключен iPhone.
В iOS 4 Framework 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>
Просто чтобы сделать заметку здесь. Я протестировал этот API на разных SIM-картах, и кажется, что имя оператора, к которому iPhone заблокирован, возвращается с [carrer carrierName]!!
Я тестировал это на 2 iphones, один заперт, а другой нет, а для заблокированного, независимо от поставщика SIM-карты, он возвращает имя оператора, в котором он заблокирован, каждый раз, когда я запускаю тестовое приложение. Обратите внимание, однако, что MNC действительно меняется!
Нет публичного API для получения имени оператора. Если вам не нужно публиковать в App Store, вы можете посмотреть на использование private 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.
Существует такой способ, однако он доступен только на iOS 4, поэтому вы не сможете использовать его в предыдущих версиях. И это, вероятно, также нарушает вашу обратную совместимость.
Получить имя оператора из строки состояния в случае, если 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
}
Для быстрых пользователей вы можете попробовать следующее:
import CoreTelephony
static var carrierName:String? {
let networkInfo = CTTelephonyNetworkInfo()
let carrier = networkInfo.subscriberCellularProvider
return carrier?.carrierName
}