iOS Detect 3G or WiFi

2019-01-01 10:25发布

问题:

I am not sure if this is possible, but I have this scenario.

I have a website displayed in my UIWebView which has the link set in a UISegmentedController. They website can detect if you are on wifi or on the 3g network.

Now the segmented controller points to 2 different pages: 1 - An iPhone friendly login screen 2 - The home page, once you are logged in.

Now here is the question:

Can I program my application to detect whether it is to WIFI or 3G (I know you can do this), but then based on the answer go to segment 1 or 2

Kind of like this:

if (iPhone device is on 3g) {
    Go to Segment 1;
} else {
    Go to Segment 0;
}

回答1:

Using the code that Apple has provided here

Reachability *reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];

NetworkStatus status = [reachability currentReachabilityStatus];

if(status == NotReachable) 
{
    //No internet
}
else if (status == ReachableViaWiFi)
{
    //WiFi
}
else if (status == ReachableViaWWAN) 
{
    //3G
}


回答2:

If you don\'t want to import Reachability library or deal with notifiers, you can use this simple synchronous method:

typedef enum {
    ConnectionTypeUnknown,
    ConnectionTypeNone,
    ConnectionType3G,
    ConnectionTypeWiFi
} ConnectionType;


+ (ConnectionType)connectionType
{
    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, \"8.8.8.8\");
    SCNetworkReachabilityFlags flags;
    BOOL success = SCNetworkReachabilityGetFlags(reachability, &flags);
    CFRelease(reachability);
    if (!success) {
        return ConnectionTypeUnknown;
    }
    BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0);
    BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0);
    BOOL isNetworkReachable = (isReachable && !needsConnection);

    if (!isNetworkReachable) {
        return ConnectionTypeNone;
    } else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) {
        return ConnectionType3G;
    } else {
        return ConnectionTypeWiFi;
    }
}


回答3:

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) :

  • iOS Detect 3G or WiFi
  • Detect carrier connection type (3G / EDGE / GPRS)
  • What are the differences between 1G, 2G, 3G, 4G and 5G?
  • CDMA2000
  • wiki 2G
  • What is the difference between CDMA and WCDMA network sim

  • What is \"EV-DO Rev. A\"?



回答4:

I made a pretty simple block based Reachability wrapper that strips all the outdated C-like Reachability code, poured into a much more Cocoa form.

Usage like:

[EPPZReachability reachHost:hostNameOrIPaddress
               completition:^(EPPZReachability *reachability)
{
    if (reachability.reachableViaCellular) [self doSomeLightweightStuff];
}];

See Reachability with blocks for everyday use at eppz!blog, or grab it directly from eppz!reachability at GitHub.

It also works with IP addresses, which turned out to be a pretty rare Reachability wrapper feature.



回答5:

For swift we can use:

func getNetworkType()->String {
    do{
        let reachability:Reachability = try Reachability.reachabilityForInternetConnection()
        do{
            try reachability.startNotifier()
            let status = reachability.currentReachabilityStatus
            if(status == .NotReachable){
                return \"\"
            }else if (status == .ReachableViaWiFi){
                return \"Wifi\"
            }else if (status == .ReachableViaWWAN){
                let networkInfo = CTTelephonyNetworkInfo()
                let carrierType = networkInfo.currentRadioAccessTechnology
                switch carrierType{
                case CTRadioAccessTechnologyGPRS?,CTRadioAccessTechnologyEdge?,CTRadioAccessTechnologyCDMA1x?: return \"2G\"
                case CTRadioAccessTechnologyWCDMA?,CTRadioAccessTechnologyHSDPA?,CTRadioAccessTechnologyHSUPA?,CTRadioAccessTechnologyCDMAEVDORev0?,CTRadioAccessTechnologyCDMAEVDORevA?,CTRadioAccessTechnologyCDMAEVDORevB?,CTRadioAccessTechnologyeHRPD?: return \"3G\"
                case CTRadioAccessTechnologyLTE?: return \"4G\"
                default: return \"\"
                }

                // Get carrier name

            }else{
                return \"\"
            }
        }catch{
            return \"\"
        }

    }catch{
        return \"\"
    }


}


回答6:

#import <ifaddrs.h>
#import <arpa/inet.h>

BOOL CheckWiFi() {

    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;

    BOOL hasWifi = NO;

    int err = getifaddrs(&interfaces);
    if(err == 0) {

        temp_addr = interfaces; 

        while(temp_addr) {

            if(temp_addr->ifa_addr->sa_family == AF_INET) {

                struct sockaddr_in *addr = (struct sockaddr_in *)temp_addr->ifa_addr;

                if(memcmp(temp_addr->ifa_name, \"en\", 2) == 0) {
                    hasWifi = YES;
                    break;
                }
            }

            temp_addr = temp_addr->ifa_next;
        }
    }

    freeifaddrs(interfaces);
    return hasWifi;
}

To check if you are in a wifi, this saves the costly check of making a connection. Check for ifa_name \"bridge\" to check for internet sharing.



回答7:

Class method is as follow

+(NSString*)connectedNetworkType {
     Reachability *reachability = [Reachability reachabilityForInternetConnection];
        [reachability startNotifier];

        NetworkStatus status = [reachability currentReachabilityStatus];

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

            }
        }
        return @\"-1\";//default unknown
}


回答8:

Here is an updated version for iOS 6 with SimplePing from apple also included. It is ARC compatible and I started from another person\'s fix to Reachability. http://elbsolutions.com/projects/reachability-with-simpleping-wrapper/

I hope this helps someone.



回答9:

If you are using Xamarin or Monotouch you can use Reachability adapted class from Xamarin GitHub repository:

https://github.com/xamarin/monotouch-samples/blob/master/ReachabilitySample/reachability.cs

So add it to your project and call Reachability.InternetConnectionStatus()



回答10:

Use this one, built with Reachability and easy to use, just a few line of code to integrate. Has a callback function to tell you when the connection changed http://huytd.github.io/datatify/