iOS Detect 3G ou WiFi

106

Je ne sais pas si cela est possible, mais j'ai ce scénario.

J'ai un site Web affiché dans mon UIWebView dont le lien est défini dans un UISegmentedController. Leur site Web peut détecter si vous êtes en wifi ou sur le réseau 3g.

Maintenant, le contrôleur segmenté pointe vers 2 pages différentes: 1 - Un écran de connexion convivial pour iPhone 2 - La page d'accueil, une fois que vous êtes connecté.

Voici maintenant la question:

Puis-je programmer mon application pour détecter si elle est en WIFI ou 3G (je sais que vous pouvez le faire), mais en fonction de la réponse, passez au segment 1 ou 2

Un peu comme ça:

if (iPhone device is on 3g) {
    Go to Segment 1;
} else {
    Go to Segment 0;
}
jwknz
la source
2
duplication possible de l' iphone SDK détecte le réseau Wifi et Carrier
Andrejs Cainikovs

Réponses:

210

Utilisation du code fourni par Apple ici

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
}
James Webster
la source
Oui Cool ça a marché !!! J'ai dû réparer les fichiers d'accessibilité car ils contenaient des erreurs pour iOS5 - mais je suis tellement heureux en ce moment. Malheureusement, je ne peux vous donner qu'un seul vote :-)
jwknz
10
Ne devriez-vous pas appeler [reachability stopNotifier]après avoir obtenu le statut?
zekel
3
Cela dépend de la portée dans laquelle vous utilisez ce code. Si c'était juste dans une méthode, reachabilityserait hors de portée et désalloué à la fin de la méthode et stopNotifierserait appelé implicitement.
James Webster
Merci pour la modification. Je suppose que c'était une ancienne version de ce code qui utilisaitReachableViaWifiNetwork
James Webster
Cela fonctionne très bien, mais n'oubliez pas d'inclure dans le projet général systemConfiguration.framework, sinon vous aurez un problème de Linker
Jevgenij Kononov
30

Si vous ne souhaitez pas importer de bibliothèque d'accessibilité ou gérer les notificateurs, vous pouvez utiliser cette méthode synchrone simple:

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;
    }
}
Pavel Alexeev
la source
Pour utiliser ce code utile, vous devez #import <SystemConfiguration / SystemConfiguration.h> et créer un lien vers SystemConfiguration.framework.
Dirk
18

Importez l' accessibilité d'Apple et essayez ceci,

#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");
    }

    }

Références (les liens peuvent être rompus à l'avenir):

Mohammad Zaid Pathan
la source
Ajoutez d'abord le framework SystemConfiguration, ouvrez ce lien github.com/tonymillion/Reachabilit 'et téléchargez le fichier et copiez Reachability.h, .m dans votre projet et importez #import "Reachability.h", #import <CoreTelephony / CTTelephonyNetworkInfo.h> et enfin copier coller au-dessus du code .....
Marquage
8

J'ai créé un wrapper d'accessibilité basé sur des blocs assez simple qui supprime tout le code d'accessibilité obsolète de type C, versé sous une forme beaucoup plus Cocoa.

Utilisation comme:

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

Consultez Accessibilité avec des blocs pour un usage quotidien sur le blog eppz!, Ou récupérez-la directement à partir de l' accessibilité eppz! Sur GitHub .

Il fonctionne également avec les adresses IP , ce qui s'est avéré être une fonctionnalité de wrapper d'accessibilité assez rare.

Geri Borbás
la source
19
Ummm pourquoi la «capture d'écran»?
QED
12
Je l'ai eu dans le billet de blog, des bonbons pour les yeux.
Geri Borbás
7

Lorsque vous utilisez iOS 12 ou plus récent, vous pouvez utiliser à la NWPathMonitorplace de la Reachabilityclasse préhistorique :

import Network // Put this on top of your class

let monitor = NWPathMonitor()

monitor.pathUpdateHandler = { path in
    if path.status != .satisfied {
        // Not connected
    }
    else if path.usesInterfaceType(.cellular) {
        // Cellular 3/4/5g connection
    }
    else if path.usesInterfaceType(.wifi) {
        // Wi-fi connection
    }
    else if path.usesInterfaceType(.wiredEthernet) {
        // Ethernet connection
    }
}

monitor.start(queue: DispatchQueue.global(qos: .background))
Ely
la source
Pouvons-nous définir quel hôte tester pour cela, comme nous pourrions le faire Reachability.reachabilityWithHostName?
agirault le
5

Pour rapide, nous pouvons utiliser:

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 ""
    }


}
Sachin Agarwal
la source
3

La méthode de classe est la suivante

+(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
}
Développeur HD
la source
2
#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;
}

Pour vérifier si vous êtes dans un wifi, cela évite la vérification coûteuse de la connexion. Recherchez ifa_name "bridge" pour vérifier le partage Internet.

Hogdotmac
la source