iOS check if cellular technology available even if the device is on WiFi

Need some help here.

I need to detect if an iOS device have (on a certain moment) cellular capabilities (No matter which one).

  • Make a phone call programmatically
  • iOS how to find country code of the user's phone number?
  • I tried to use reachability class, but the problem start when the user is connected to WiFi, because if so – reachability can’t detect cellular

    I also tried to use this code:

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

    But even if I’m turning off cellular data its returning CTRadioAccessTechnologyLTE i can’t understand why.

    Edit

    I tried to enumerate the network interface like the suggastion in the answer below, but the pdp_ip0 is still up and getting an IP.

    struct ifaddrs* interfaces = NULL;
        struct ifaddrs* temp_addr = NULL;
    
        // retrieve the current interfaces - returns 0 on success
        NSInteger success = getifaddrs(&interfaces);
        if (success == 0)
        {
            // Loop through linked list of interfaces
            temp_addr = interfaces;
            while (temp_addr != NULL)
            {
                NSString* name = [NSString stringWithUTF8String:temp_addr->ifa_name];
    
    
    
                NSString *address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
    
                NSLog(@" Name:%@   IP:%@",name,address);
    
    
                temp_addr = temp_addr->ifa_next;
    
            }
        }
    
        // Free memory
        freeifaddrs(interfaces);
    

    Output on cell disable:

    2015-08-04 11:58:33.297 check[405:46916]  Name:pdp_ip0   IP:255.7.0.0
    

    Output on cell enabled (the pdp_ip0 appear twice)

    2015-08-04 11:59:08.914 check[405:46916]  Name:pdp_ip0   IP:255.7.0.0
    2015-08-04 11:59:08.914 check[405:46916]  Name:pdp_ip0 P:10.130.112.****)
    

    I dont want to realay on it appearing twice, is there a better way?

    Can anyone can have any idea how can I get this to work? (without using hidden API).

    Thanks a lot.

    2 Solutions Collect From Internet About “iOS check if cellular technology available even if the device is on WiFi”

    You can get that info by enumerating network interfaces. Cellular interface is named pdp_ip0. When cellular interface is active and cellular data is enabled it will be up and have an IP address. When you disable cellular data (or don’t have cellular connection at all) interface will be down.

    UPDATE

    I will say again, please read my answers carefully. Check IFF_UP, otherwise you’re checking non-active interfaces. pdp_ip0 appears twice because one is IPv4 and other is IPv6 – you need to check ifa_addr->sa_family. 255.7.0.0 is a garbage value because that’s not a proper way to retrieve an IPv6 address – you need to use inet_ntop. If you do everything correctly then your problem will be solved. Or just try reading documentation – that’s all basic well-known APIs that’s covered everywhere on the internet.

    Your output exactly matches what I’m seeing on my device:

    • Output on cell disable – here you have IPv6 pdp_ip0 interface but it’s down
    • Output on cell enabled – here you see two pdp_ip0 interfaces – first is IPv6, second is IPv4. Both of them will be up

    If anyone needs – this solution I wrote:

    - (BOOL)isHaveCell{
    
        struct ifaddrs* interfaces = NULL;
    
        struct ifaddrs* temp_addr = NULL;
    
        // retrieve the current interfaces - returns 0 on success
        NSInteger success = getifaddrs(&interfaces);
        if (success == 0)
        {
            // Loop through linked list of interfaces
            temp_addr = interfaces;
            while (temp_addr != NULL)
            {
    
                NSString *name = [NSString stringWithUTF8String:temp_addr->ifa_name];
    
    
                if ([name isEqualToString:@"pdp_ip0"] && temp_addr->ifa_addr->sa_family ==2 ) {
    
                    return TRUE;
    
                }
    
                temp_addr = temp_addr->ifa_next;
    
            }
        }
    
        // Free memory
        freeifaddrs(interfaces);
    
        return FALSE;
    
    }