1

Is there a way in Swift to get a notification every time the cellular connection type changes (e.g. from 3G to Edge) without polling the state regularly?

I know how to determine the connection type with the serviceCurrentRadioAccessTechnology property but failed to wrap it into a KVO or to add an observer.

The best attempt I found was using the NotificationCenter but in my case it did not notify on connection changes.

If anyone could provide an example or give me a hint on how to implement this I would be very thankful.

  • Can [this](https://developer.apple.com/documentation/coretelephony/cttelephonynetworkinfo/3024512-servicesubscribercellularprovide) help you ? You define a var in the global subscriber with a function that will be called upon changes. – Ptit Xav Oct 19 '22 at 11:50
  • According to the documentation this only gets raised if the provider has changed but not on switching connection types. – KannonLyriq Oct 20 '22 at 05:01
  • I think this is duplicate of https://stackoverflow.com/a/36605546/2894790 – Christos Koninis Oct 20 '22 at 08:55
  • Does this answer your question? [How to detect at realtime the increase/decrease of cellular signal power in iOS](https://stackoverflow.com/questions/36481141/how-to-detect-at-realtime-the-increase-decrease-of-cellular-signal-power-in-ios) – Christos Koninis Oct 20 '22 at 08:56

1 Answers1

1

This is Objective-C code, you just need to convert it to Swift

Import Apple's Reachability and try this,

#import "Reachability.h"
#import <CoreTelephony/CTTelephonyNetworkInfo.h>

//Try this
Reachability *reachability = [Reachability reachabilityForInternetConnection];
    [reachability startNotifier];
    
    NetworkStatus status = [reachability currentReachabilityStatus];
    
    if(status == NotReachable)
    {
       NSLog(@"none");
        //No internet
    }
    else if (status == ReachableViaWiFi)
    {
        NSLog(@"Wifi");
        //WiFi
    }
    else if (status == ReachableViaWWAN)
    {
        NSLog(@"WWAN");
    
    
    //connection type
    CTTelephonyNetworkInfo *netinfo = [[CTTelephonyNetworkInfo alloc] init];
    _carrier = [[netinfo subscriberCellularProvider] carrierName];
    
    if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS]) {
        NSLog(@"2G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge]) {
        NSLog(@"2G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyWCDMA]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSDPA]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSUPA]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMA1x]) {
        NSLog(@"2G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyeHRPD]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
        NSLog(@"4G");
    }
    
    }

References(Links may broke in future) :

David Ansermot
  • 6,052
  • 8
  • 47
  • 82
  • Thank you very much for your answer, when testing this on the simulator in combination with the Network Link Conditioner I still could not get a notification on network changes. Did you manage to run this successfully? Also i wonder if there is a more recent solution since CTRadioAccessTechnologyDidChangeNotification is deprecated in iOS 12. – KannonLyriq Oct 24 '22 at 07:12