iOS 3G oder WiFi erkennen

106

Ich bin nicht sicher, ob dies möglich ist, aber ich habe dieses Szenario.

In meinem UIWebView wird eine Website angezeigt, auf der der Link in einem UISegmentedController festgelegt ist. Die Website kann erkennen, ob Sie sich im WLAN oder im 3G-Netzwerk befinden.

Jetzt zeigt der segmentierte Controller auf 2 verschiedene Seiten: 1 - Ein iPhone-freundlicher Anmeldebildschirm 2 - Die Startseite, sobald Sie angemeldet sind.

Hier ist die Frage:

Kann ich meine Anwendung so programmieren, dass sie erkennt, ob es sich um WIFI oder 3G handelt (ich weiß, dass Sie dies tun können), aber dann basierend auf der Antwort zu Segment 1 oder 2 gehen

Ein bisschen wie das:

if (iPhone device is on 3g) {
    Go to Segment 1;
} else {
    Go to Segment 0;
}
jwknz
quelle
2
Mögliches Duplikat des iPhone SDK erkennt Wifi und Carrier Netzwerk
Andrejs Cainikovs

Antworten:

210

Verwenden Sie den Code, den Apple hier bereitgestellt hat

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
quelle
Ja cool es hat funktioniert !!! Ich musste einige Korrekturen an den Erreichbarkeitsdateien vornehmen, da diese Fehler für iOS5 enthielten - aber ich bin jetzt so glücklich. Leider kann ich dir nur 1 Stimme geben :-)
jwknz
10
Sollten Sie nicht anrufen, [reachability stopNotifier]nachdem Sie den Status haben?
Zekel
3
Dies hängt vom Umfang ab, in dem Sie diesen Code verwenden. Wenn dies nur in einer Methode reachabilitywäre , würde dies den Rahmen verlassen und am Ende der Methode freigegeben und stopNotifierimplizit aufgerufen werden.
James Webster
Danke für die Bearbeitung. Ich nehme an, es war eine alte Version dieses Codes, die verwendet wurdeReachableViaWifiNetwork
James Webster
Das funktioniert gut, aber vergessen Sie nicht, in das allgemeine Projekt systemConfiguration.framework aufzunehmen, sonst erhalten Sie das Linker-Problem
Jevgenij Kononov
30

Wenn Sie keine Erreichbarkeitsbibliothek importieren oder sich nicht mit Benachrichtigern befassen möchten, können Sie diese einfache synchrone Methode verwenden:

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
quelle
Um diesen hilfreichen Code zu verwenden, müssen Sie <SystemConfiguration / SystemConfiguration.h> importieren und einen Link zu SystemConfiguration.framework erstellen.
Dirk
18

Importieren Sie Apples Erreichbarkeit und versuchen Sie dies,

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

    }

Referenzen (Links können in Zukunft unterbrochen werden):

Mohammad Zaid Pathan
quelle
Fügen Sie zuerst das SystemConfiguration-Framework hinzu, öffnen Sie diesen Link github.com/tonymillion/Reachabilit 'und laden Sie die Datei herunter, kopieren Sie Reachability.h, .m in Ihr Projekt und importieren Sie #import "Reachability.h", #import <CoreTelephony / CTTelephonyNetworkInfo.h> und schließlich kopieren Einfügen über Code .....
Markierung
8

Ich habe einen ziemlich einfachen blockbasierten Reachability-Wrapper erstellt, der den gesamten veralteten C-ähnlichen Reachability-Code entfernt und in eine viel mehr Kakao-Form gegossen hat.

Verwendung wie:

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

Siehe Erreichbarkeit mit Blöcken für den täglichen Gebrauch auf eppz! Blog oder greifen Sie direkt auf eppz! Erreichbarkeit bei GitHub zu .

Es funktioniert auch mit IP-Adressen , was sich als ziemlich seltene Reachability-Wrapper-Funktion herausstellte.

Geri Borbás
quelle
19
Ummm warum der 'Screenshot'?
QED
12
Ich hatte es aus dem Blog-Beitrag, Süßigkeiten für die Augen.
Geri Borbás
6

Wenn Sie iOS 12 oder höher verwenden, können Sie NWPathMonitoranstelle der prähistorischen ReachabilityKlasse Folgendes verwenden:

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
quelle
Können wir definieren, mit welchem ​​Host wir das testen sollen, wie wir es könnten Reachability.reachabilityWithHostName?
Agirault
5

Für schnell können wir verwenden:

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
quelle
3

Die Klassenmethode ist wie folgt

+(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
}
HD-Entwickler
quelle
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;
}

Um zu überprüfen, ob Sie sich in einem WLAN befinden, erspart dies die kostspielige Überprüfung des Verbindungsaufbaus. Suchen Sie nach ifa_name "bridge", um nach Internetfreigabe zu suchen.

Hogdotmac
quelle
0

Hier ist eine aktualisierte Version für iOS 6 mit SimplePing von Apple. Es ist ARC-kompatibel und ich habe mit dem Fix einer anderen Person auf Erreichbarkeit begonnen. http://elbsolutions.com/projects/reachability-with-simpleping-wrapper/

Ich hoffe das hilft jemandem.

Etienne Bley
quelle
Wenn Sie ein Beispiel für seine Verwendung könnten.
Mike D
-2

Verwenden Sie diese, mit Erreichbarkeit erstellte und benutzerfreundliche, nur wenige Codezeile zum Integrieren. Hat eine Rückruffunktion, die Ihnen mitteilt, wann sich die Verbindung geändert hat http://huytd.github.io/datatify/

Huy Tran
quelle
Diese Verwendung wieder Erreichbarkeit
Stephan