Detect carrier connection type (3G / EDGE / GPRS)
Asked Answered
A

4

21

How can i get the type of connection of a carrier network?

  • I'm able to get if connection is WIFI or WWAN using Reachability class
  • I'm able to get network flags

    Reachability Flag Status: WR t------ localWiFiStatusForFlags

  • I'm able to get WIFI SSID using CaptiveNetwork

Supported interfaces: ( en0 )

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

But i'm not able to differenziate 3G, EDGE or GPRS connection.

Any idea also using iOS private API?

thanks.

Ariminum answered 15/6, 2012 at 11:16 Comment(0)
E
61

From iOS 7 on you can use:

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);
}];

I have also found this to detect a slow or fast connection:

- (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;
}
Erinerina answered 30/12, 2013 at 13:55 Comment(8)
Don't forget to put #import <CoreTelephony/CTTelephonyNetworkInfo.h> at the top of your file.Antependium
Is this a private API? I don't see it documented in CTTelephonyNetworkInfo class.Edlun
Thanks @Ben , but I doubt that CDMA1x is fastAtonement
You are right, I'll change it to NO. The speed seems to be at most 144kbps, which can be compared with Edge speeds. Thanks Jason Lee :) +1Erinerina
This is not correct, since on device I get HSDPA, no matter if I'm on 3G or I have Cellular Data turned off.Headrest
Have you checked when your wifi is on and run this code, it returns Edge or 3G instead of Wifi. Also this code retuns null when remove SIM from device. iPad, iPod without SIM are also returns null.Janeljanela
@BenGroot can we switch LTE to 3g/2g using MDM commands? for a enteprise apps.Doll
@BenGroot....On which condition we can call above method...pls explain little bit more how to call that method....- (BOOL)isFast:(NSString*)radioAccessTechnologyTillandsia
A
5

Here the OLD solution, using private API, in particular SoftwareUpdateServices.framework

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

It returns:

0: NO DATA
1: WIFI
2: GPRS/EDGE
3: 3G

hope this helps community.

Ariminum answered 20/6, 2012 at 12:48 Comment(6)
actually you have to call NSLog(@"TYPE: %d", [[[NetworkMonitor alloc] init] currentNetworkType]);Tombstone
Doesn't Apple rejects this cause of the private API?Erinerina
@BenGroot Probably yes. This method use private api.Ariminum
It is said that one could use key-value coding to determine the network-reachabiliy values for ios 6 and below without using CTTelephonyNetworkInfo which is only avaliable on ios 7 and above.Literary
Apple will kill your app :-P for private APIToque
@Toque of course. But my app was not in the store.Ariminum
T
1

The accepted answer isn't working on iOS 10. I found a workaround and setup a timer in AppDelegate which is checking the property currentRadioAccessTechnology every 5 seconds. Therefore we also need a function to check if WIFI connection is available instead of radio access technology.

Check if WIFI Connection is available:

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
}

Setup the timer like this:

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

Selector which is called every 5 seconds:

    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
Team answered 31/5, 2017 at 10:36 Comment(0)
D
-1

I am working on an iPhone application that requires the ability to recognize which type of internet connection is currently being used (Wifi, 3G, Edge, etc). I found a simple way to check by using Apples Reachability sample code. There seems to be a shortage of information about this online, I hope this can help someone.

First copy Reachability.m/.h into your project and include #include "Reachability.h" into your class.

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];

This code may not be the best way to accomplish this, but it appears to be the most simple approach.

Dissyllable answered 15/6, 2012 at 11:22 Comment(2)
I already use Reachability class to detect difference between WIFI or CARRIER. I want to detect GPRS or EDGE or 3G, not all toghether!Ariminum
There is no possible to recognize GPRS or EDGE or 3G. Only way is recognize all together with flag kSCNetworkReachabilityFlagsIsWWANForeclose

© 2022 - 2024 — McMap. All rights reserved.