Определить тип подключения оператора связи (3G / EDGE / GPRS)

Как я могу получить тип подключения операторской сети?

  • Я могу узнать, используется ли соединение WIFI или WWAN, используя класс Reachability
  • # P2 #
    # P3 #
  • Я могу получить WIFI SSID, используя CaptiveNetwork

Поддерживаемые интерфейсы: (en0)

en0 => {  
    BSSID = "xx:xx:xx:xx:xx:xx";  
    SSID = MyWifiNetwork;  
    SSIDDATA = <x1x1x1x1 x1x1x1x1 x1>;  
}  

Но я не могу различать соединения 3G, EDGE или GPRS.

Есть идеи также использовать частный API iOS?

благодаря.


person elp    schedule 15.06.2012    source источник


Ответы (4)


Начиная с iOS 7, вы можете использовать:

CTTelephonyNetworkInfo *telephonyInfo = [CTTelephonyNetworkInfo new];
NSLog(@"Current Radio Access Technology: %@", telephonyInfo.currentRadioAccessTechnology);
[NSNotificationCenter.defaultCenter addObserverForName:CTRadioAccessTechnologyDidChangeNotification 
                                                object:nil 
                                                 queue:nil 
                                            usingBlock:^(NSNotification *note) 
{
    NSLog(@"New Radio Access Technology: %@", telephonyInfo.currentRadioAccessTechnology);
}];

Я также обнаружил, что это обнаруживает медленное или быстрое соединение:

- (BOOL)isFast:(NSString*)radioAccessTechnology {
    if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS]) {
        return NO;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge]) {
        return NO;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyWCDMA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSDPA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSUPA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMA1x]) {
        return NO;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyeHRPD]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
        return YES;
    }

    return YES;
}
person Ben Groot    schedule 30.12.2013
comment
Не забудьте поместить #import ‹CoreTelephony / CTTelephonyNetworkInfo.h› в начало файла. - person dev; 27.10.2014
comment
Это частный API? Я не вижу это задокументировано в классе CTTelephonyNetworkInfo. - person nyus2006; 11.11.2014
comment
Спасибо @Ben, но я сомневаюсь, что CDMA1x быстрый - person Jason Lee; 28.01.2015
comment
Вы правы, я поменяю на НЕТ. Кажется, что скорость составляет не более 144 кбит / с, что можно сравнить со скоростью Edge. Спасибо, Джейсон Ли :) +1 - person Ben Groot; 28.01.2015
comment
Это неверно, поскольку на устройстве я использую HSDPA, независимо от того, использую ли я 3G или у меня отключены сотовые данные. - person Kex; 13.09.2015
comment
Вы проверили, когда ваш Wi-Fi включен, и запустили этот код, он возвращает Edge или 3G вместо Wi-Fi. Также этот код возвращается к нулю при извлечении SIM-карты из устройства. iPad, iPod без SIM-карты также возвращают null. - person Pratik Patel; 23.11.2015
comment
@BenGroot, можем ли мы переключить LTE на 3g / 2g с помощью команд MDM? для корпоративных приложений. - person vishy; 14.04.2016
comment
@BenGroot .... При каком условии мы можем вызвать вышеуказанный метод ... пожалуйста, объясните немного подробнее, как вызвать этот метод .... - (BOOL) isFast: (NSString *) radioAccessTechnology - person Priya; 29.05.2017

Здесь OLD решение, с использованием частного API, в частности SoftwareUpdateServices.framework

Class NetworkMonitor = NSClassFromString(@"SUNetworkMonitor");
NSLog(@"TYPE: %d", [NetworkMonitor currentNetworkType]);

Он возвращает:

0: НЕТ ДАННЫХ
1: WIFI
2: GPRS / EDGE
3: 3G

надеюсь, что это поможет сообществу.

person elp    schedule 20.06.2012
comment
на самом деле вам нужно вызвать NSLog (@TYPE:% d, [[[NetworkMonitor alloc] init] currentNetworkType]); - person DanEEStar; 28.06.2012
comment
Разве Apple не отвергает эту причину частного API? - person Ben Groot; 30.12.2013
comment
@BenGroot Наверное, да. Этот метод использует частный api. - person elp; 20.01.2014
comment
Говорят, что можно использовать кодирование «ключ-значение» для определения значений доступности сети для iOS 6 и ниже без использования CTTelephonyNetworkInfo, который доступен только в iOS 7 и выше. - person NicTesla; 19.03.2014
comment
Apple убьет ваше приложение :-P для частного API - person byJeevan; 07.11.2016
comment
@byJeevan, конечно. Но моего приложения в магазине не оказалось. - person elp; 07.11.2016

Принятый ответ не работает на iOS 10. Я нашел обходной путь и установил таймер в AppDelegate, который проверяет свойство currentRadioAccessTechnology каждые 5 секунд. Поэтому нам также нужна функция для проверки наличия WIFI-соединения вместо технологии радиодоступа.

Проверьте, доступно ли WIFI соединение:

class func isConnectedToWlan() -> Bool {
    var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, 
                         sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)

    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
        }
    }

    var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
    if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
        return false
    }

    //Only Working for WIFI
     let isReachable = flags == .reachable
     let needsConnection = flags == .connectionRequired

     return isReachable && !needsConnection
}

Настройте таймер следующим образом:

Timer.scheduledTimer(timeInterval: TimeInterval.seconds(5.0), target: self, selector:      
                           #selector(showNetworkMessage), userInfo: nil, repeats: true)

Селектор, который вызывается каждые 5 секунд:

    guard !Reachability.isConnecteToWlan() else {
        //Connected to WLAN
        return
    }
    guard let currentRadioAccessTechnology = info.currentRadioAccessTechnology else {
        // No internet connection
        return
    }
    guard (currentRadioAccessTechnology == CTRadioAccessTechnologyGPRS 
             || currentRadioAccessTechnology == CTRadioAccessTechnologyEdge) else {
        // 3G, LTE fast radio access Technology
        return
    }

    if lastRadioAccessTechnology != nil {
        guard let lastRadioAccessTechnology = lastRadioAccessTechnology, 
            (lastInfo != currentRadioAccessTechnology || 
              lastInfo != currentRadioAccessTechnology) else {
            //Internet connection did not change
            return
        }
    }
    // Internet connection changed to Edge or GPRS
    // Store lastRadioAccessTechnology to check if internet connection changed
    lastRadioAccessTechnology = currentRadioAccessTechnology
person cb89    schedule 31.05.2017

Я работаю над приложением для iPhone, которое требует способности распознавать, какой тип подключения к Интернету используется в настоящее время (Wi-Fi, 3G, Edge и т. Д.). Я нашел простой способ проверить, используя образец кода Apples Reachability. Похоже, в Интернете не хватает информации об этом, я надеюсь, что это может кому-то помочь.

Сначала скопируйте Reachability.m / .h в свой проект и включите #include "Reachability.h" в свой класс.

Reachability *reach = [[Reachability alloc]init];
if (reach.internetConnectionStatus == NotReachable) {
    NSLog(@"No Connection Found");
} else if (reach.internetConnectionStatus == ReachableViaCarrierDataNetwork) {
    NSLog(@"3G or Edge");
} else if (reach.internetConnectionStatus == ReachableViaWiFiNetwork) {
    NSLog(@"Wifi Connection");
}
[reach release];

Этот код может быть не лучшим способом добиться этого, но, похоже, это самый простой подход.

person Tiffany    schedule 15.06.2012
comment
Я уже использую класс Reachability для определения разницы между WIFI и CARRIER. Я хочу обнаружить GPRS, EDGE или 3G, но не все вместе! - person elp; 15.06.2012
comment
Нет возможности распознать GPRS, EDGE или 3G. Единственный способ - распознать все вместе с флагом kSCNetworkReachabilityFlagsIsWWAN - person Michal Zaborowski; 15.06.2012