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

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
}

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

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


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.


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

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


}

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
}

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.




-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/


Diese Verwendung wieder Erreichbarkeit
Stephan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.