Wie überprüfe ich, ob unter iOS oder macOS eine aktive Internetverbindung besteht?

1325

Ich möchte überprüfen, ob ich unter iOS mit den Cocoa Touch- Bibliotheken oder unter macOS mit den Cocoa- Bibliotheken eine Internetverbindung habe .

Ich habe einen Weg gefunden, dies mit einem zu tun NSURL. Die Art und Weise, wie ich es getan habe, scheint ein bisschen unzuverlässig zu sein (weil sogar Google eines Tages ausfallen und sich auf einen Dritten verlassen könnte, scheint schlecht zu sein), und während ich nach einer Antwort von einigen anderen Websites suchen konnte, wenn Google nicht antwortete, war dies der Fall scheint verschwenderisch und ein unnötiger Aufwand für meine Bewerbung.

- (BOOL) connectedToInternet
{
    NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];
    return ( URLString != NULL ) ? YES : NO;
}

Ist das, was ich getan habe, schlecht (ganz zu schweigen davon, dass stringWithContentsOfURLes in iOS 3.0 und macOS 10.4 veraltet ist) und wenn ja, wie kann ich dies besser erreichen?

Brock Woolf
quelle
11
Eher return (BOOL)URLString;oder noch besser, return !!URLStringoderreturn URLString != nil
3
Ich weiß nicht, was Ihr Anwendungsfall ist, aber wenn Sie können, ist es vorzuziehen, die Anfrage zu versuchen und etwaige Fehler wie fehlende Verbindung zu behandeln. Wenn Sie dies nicht tun können, gibt es hier in diesem Fall viele gute Ratschläge.
SK9
2
Ihre Lösung ist klug und ich bevorzuge sie. Sie können auch verwenden NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://twitter.com/getibox"] encoding:NSUTF8StringEncoding error:nil];, um die lästige Warnung loszuwerden.
Abdelrahman Eid
4
Versuchen Sie, die Erreichbarkeitsklasse über den folgenden Link zu verwenden. Sie funktioniert für Sie. github.com/tonymillion/Reachability
Dhaval H. Nena
4
Für diejenigen, die kürzlich diese Antwort gefunden haben: stackoverflow.com/a/8813279
afollestad

Antworten:

1284

Wichtig : Diese Prüfung sollte immer asynchron durchgeführt werden. Die meisten der folgenden Antworten sind synchron. Seien Sie also vorsichtig, sonst frieren Sie Ihre App ein.


Schnell

1) Installation über CocoaPods oder Karthago: https://github.com/ashleymills/Reachability.swift

2) Erreichbarkeit über Verschlüsse testen

let reachability = Reachability()!

reachability.whenReachable = { reachability in
    if reachability.connection == .wifi {
        print("Reachable via WiFi")
    } else {
        print("Reachable via Cellular")
    }
}

reachability.whenUnreachable = { _ in
    print("Not reachable")
}

do {
    try reachability.startNotifier()
} catch {
    print("Unable to start notifier")
}

Ziel c

1) Fügen Sie SystemConfigurationdem Projekt ein Framework hinzu, aber machen Sie sich keine Sorgen, dass Sie es irgendwo einfügen

2) Fügen Sie die Version von Tony Million von Reachability.hund Reachability.mzum Projekt hinzu (hier zu finden: https://github.com/tonymillion/Reachability )

3) Aktualisieren Sie den Schnittstellenabschnitt

#import "Reachability.h"

// Add this to the interface in the .m file of your view controller
@interface MyViewController ()
{
    Reachability *internetReachableFoo;
}
@end

4) Implementieren Sie diese Methode dann in die .m-Datei Ihres View Controllers, die Sie aufrufen können

// Checks if we have an internet connection or not
- (void)testInternetConnection
{   
    internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"];

    // Internet is reachable
    internetReachableFoo.reachableBlock = ^(Reachability*reach)
    {
        // Update the UI on the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"Yayyy, we have the interwebs!");
        });
    };

    // Internet is not reachable
    internetReachableFoo.unreachableBlock = ^(Reachability*reach)
    {
        // Update the UI on the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"Someone broke the internet :(");
        });
    };

    [internetReachableFoo startNotifier];
}

Wichtiger Hinweis: Die ReachabilityKlasse ist eine der am häufigsten verwendeten Klassen in Projekten, sodass Sie möglicherweise auf Namenskonflikte mit anderen Projekten stoßen. In diesem Fall müssen Sie eines der Paare Reachability.hund Reachability.mDateien in etwas anderes umbenennen , um das Problem zu beheben.

Hinweis: Die von Ihnen verwendete Domain spielt keine Rolle. Es wird nur nach einem Gateway zu einer beliebigen Domain gesucht.

Ich wurde ausgeraubt
quelle
4
@gonzobrains: Die Domain, die Sie verwenden, spielt keine Rolle. Es wird nur nach einem Gateway zu einer beliebigen Domain gesucht.
Ich wurde am
3
@KaanDedeoglu Es ist nur ein Beispiel, verwenden Sie eine beliebige Domain. Es wird lediglich nach einem Gateway zum Internet gesucht, nicht jedoch, ob die Domain tatsächlich verfügbar ist.
Ich wurde
1
Übrigens müssen Sie SystemConfiguration.frameworkdem Projekt auch etwas hinzufügen (für Methode 1).
Wiseindy
2
Verwenden Sie www.appleiphonecell.com anstelle von google.com - genau aus diesem Grund wurde diese URL von Apple erstellt.
Smikey
1
Die Nutzung von www.appleiphonecell.com ist jetzt (2018) eine schlechte Wahl. Es leitet jetzt zu Apple.com weiter, einer HTML-Datei mit> 40 KB. Zurück zu google.com - es sind nur 11 KB. BTW google.com/m ist gleich groß, soll aber um 120 ms langsamer sein.
BlueskyMed
310

Ich mag es, die Dinge einfach zu halten. Ich mache das so:

//Class.h
#import "Reachability.h"
#import <SystemConfiguration/SystemConfiguration.h>

- (BOOL)connected;

//Class.m
- (BOOL)connected
{
    Reachability *reachability = [Reachability reachabilityForInternetConnection];
    NetworkStatus networkStatus = [reachability currentReachabilityStatus];
    return networkStatus != NotReachable;
}

Dann benutze ich dies immer dann, wenn ich sehen möchte, ob ich eine Verbindung habe:

if (![self connected]) {
    // Not connected
} else {
    // Connected. Do some Internet stuff
}

Diese Methode wartet nicht auf geänderte Netzwerkstatus, um Dinge zu erledigen. Es testet nur den Status, wenn Sie danach fragen.

Cannyboy
quelle
Hallo @msec, Sie können Andrew Zimmer Lösung auf dieser Seite versuchen, es funktioniert gut mit ADSL getrennt (und WiFi verbunden)
Williew
1
Für diejenigen, die einfach kopieren und einfügen, wie ich es mit dem obigen Code getan habe. Fügen Sie SystemConfiguration.framework auch manuell hinzu, da sonst ein Verknüpfungsfehler angezeigt wird.
Iftikhar Ali Ansari
Immer so erreichbar, wenn ich mich mit WiFi verbinde. WiFi bedeutet nicht, dass es eine Internetverbindung hat. Ich möchte die Internetverbindung überprüfen, auch wenn sie über eine WiFi-Verbindung verfügt. Können Sie mir bitte helfen?
Wesley
@wesley Wie hast du es gelöst?
Keselme
145

Mit dem Erreichbarkeitscode von Apple habe ich eine Funktion erstellt, die dies korrekt überprüft, ohne dass Sie Klassen einschließen müssen.

Fügen Sie das SystemConfiguration.framework in Ihr Projekt ein.

Machen Sie einige Importe:

#import <sys/socket.h>
#import <netinet/in.h>
#import <SystemConfiguration/SystemConfiguration.h>

Rufen Sie jetzt einfach diese Funktion auf:

/*
Connectivity testing code pulled from Apple's Reachability Example: https://developer.apple.com/library/content/samplecode/Reachability
 */
+(BOOL)hasConnectivity {
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;

    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
    if (reachability != NULL) {
        //NetworkStatus retVal = NotReachable;
        SCNetworkReachabilityFlags flags;
        if (SCNetworkReachabilityGetFlags(reachability, &flags)) {
            if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
            {
                // If target host is not reachable
                return NO;
            }

            if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
            {
                // If target host is reachable and no connection is required
                //  then we'll assume (for now) that your on Wi-Fi
                return YES;
            }


            if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
                 (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
            {
                // ... and the connection is on-demand (or on-traffic) if the
                //     calling application is using the CFSocketStream or higher APIs.

                if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
                {
                    // ... and no [user] intervention is needed
                    return YES;
                }
            }

            if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
            {
                // ... but WWAN connections are OK if the calling application
                //     is using the CFNetwork (CFSocketStream?) APIs.
                return YES;
            }
        }
    }

    return NO;
}

Und es ist iOS 5 für Sie getestet.

Andrew Zimmer
quelle
@JezenThomas Dies führt die Internetprüfung nicht asynchron durch, weshalb sie "viel schlanker" ist. Sie sollten dies immer asynchron tun, indem Sie Benachrichtigungen abonnieren, damit Sie die App bei diesem Vorgang nicht auflegen.
Ich wurde
Vielen Dank, diese Arbeit, auch wenn Sie WLAN-ADSL verwenden und ADSL nicht verbunden ist, ist genau das, was ich brauche.
Williew
5
Dadurch geht Speicher verloren - die Lesbarkeitsstruktur (Objekt, Objekt) muss mit CFRelease () freigegeben werden.
Russell Mull
@RussellMull ... eine Idee, wie man das Leck behebt?
i_raqz
Seltsam, dass diese Antwort 2 Jahre vor meiner (bei einer als Duplikat markierten Frage) genau dieselbe ist wie meine, aber ich habe sie bis heute nie gesehen.
ArtOfWarfare
121

Früher war dies die richtige Antwort, aber jetzt ist sie veraltet, da Sie stattdessen Benachrichtigungen zur Erreichbarkeit abonnieren sollten. Diese Methode prüft synchron:


Sie können die Erreichbarkeitsklasse von Apple verwenden. Außerdem können Sie überprüfen, ob Wi-Fi aktiviert ist:

Reachability* reachability = [Reachability sharedReachability];
[reachability setHostName:@"www.example.com"];    // Set your host name here
NetworkStatus remoteHostStatus = [reachability remoteHostStatus];

if (remoteHostStatus == NotReachable) { }
else if (remoteHostStatus == ReachableViaWiFiNetwork) { }
else if (remoteHostStatus == ReachableViaCarrierDataNetwork) { }

Die Erreichbarkeitsklasse wird nicht mit dem SDK geliefert, sondern ist Teil dieser Apple-Beispielanwendung . Laden Sie es einfach herunter und kopieren Sie Reachability.h / m in Ihr Projekt. Außerdem müssen Sie Ihrem Projekt das SystemConfiguration-Framework hinzufügen.

Daniel Rinser
quelle
6
Siehe meinen Kommentar oben darüber, dass die Erreichbarkeit nicht so verwendet wird. Verwenden Sie es im asynchronen Modus und abonnieren Sie die gesendeten Benachrichtigungen - nicht.
Kendall Helmstetter Gelner
Dieser Code ist ein guter Ausgangspunkt für Dinge, die Sie festlegen müssen, bevor Sie die Delegatmethoden für die Erreichbarkeitsklasse verwenden können.
Brock Woolf
82

Hier ist eine sehr einfache Antwort:

NSURL *scriptUrl = [NSURL URLWithString:@"http://www.google.com/m"];
NSData *data = [NSData dataWithContentsOfURL:scriptUrl];
if (data)
    NSLog(@"Device is connected to the Internet");
else
    NSLog(@"Device is not connected to the Internet");

Die URL sollte auf eine extrem kleine Website verweisen. Ich verwende hier die mobile Website von Google, aber wenn ich einen zuverlässigen Webserver hätte, würde ich eine kleine Datei mit nur einem Zeichen hochladen , um maximale Geschwindigkeit zu erzielen.

Wenn Sie nur prüfen möchten, ob das Gerät irgendwie mit dem Internet verbunden ist, würde ich auf jeden Fall die Verwendung dieser einfachen Lösung empfehlen. Wenn Sie wissen möchten, wie der Benutzer verbunden ist, ist die Verwendung der Erreichbarkeit der richtige Weg.

Achtung: Dadurch wird Ihr Thread kurz blockiert, während die Website geladen wird. In meinem Fall war dies kein Problem, aber Sie sollten dies berücksichtigen (Dank an Brad für den Hinweis).

Erik
quelle
10
Ich mag diese Idee wirklich, aber ich würde sagen, für die 99,999% ige Zuverlässigkeit bei gleichzeitiger Beibehaltung einer kleinen Antwortgröße gehen Sie zu www.google.com/m, der mobilen Ansicht für Google.
Rwyland
1
Tolle Lösung @Erik. Ich empfehle Ihnen auch, www.google.com anstelle von www.google.com/m zu verwenden, wie rwyland sagte. Es ist komisch, aber von meinem Test dauert die mobile Version immer etwa 120
ms
4
Apple-Dokumente empfehlen, dies nicht zu tun, da es den Thread in einem langsamen Netzwerk blockieren kann und dazu führen kann, dass die App in iOS beendet wird
Brad Thomas
Vielen Dank für das positive Feedback. Stimmen Sie zu, dass www.google.com/m aufgrund der Zuverlässigkeit die beste Lösung ist!
Erik
3
LOL, ich bin sicher, Google weiß es zu schätzen, dass Sie vorschlagen, dass Personen sie als Internet-Check-Ressource verwenden.
mxcl
73

So mache ich das in meinen Apps: Ein 200-Status-Antwortcode garantiert zwar nichts, ist aber für mich stabil genug. Dies erfordert nicht so viel Laden wie die hier veröffentlichten NSData-Antworten, da meine nur die HEAD-Antwort überprüft.

SWIFT-Code

func checkInternet(flag:Bool, completionHandler:(internet:Bool) -> Void)
{
    UIApplication.sharedApplication().networkActivityIndicatorVisible = true

    let url = NSURL(string: "http://www.google.com/")
    let request = NSMutableURLRequest(URL: url!)

    request.HTTPMethod = "HEAD"
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
    request.timeoutInterval = 10.0

    NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.mainQueue(), completionHandler:
    {(response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in

        UIApplication.sharedApplication().networkActivityIndicatorVisible = false

        let rsp = response as! NSHTTPURLResponse?

        completionHandler(internet:rsp?.statusCode == 200)
    })
}

func yourMethod()
{
    self.checkInternet(false, completionHandler:
    {(internet:Bool) -> Void in

        if (internet)
        {
            // "Internet" aka Google URL reachable
        }
        else
        {
            // No "Internet" aka Google URL un-reachable
        }
    })
}

Ziel-C-Code

typedef void(^connection)(BOOL);

- (void)checkInternet:(connection)block
{
    NSURL *url = [NSURL URLWithString:@"http://www.google.com/"];
    NSMutableURLRequest *headRequest = [NSMutableURLRequest requestWithURL:url];
    headRequest.HTTPMethod = @"HEAD";

    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    defaultConfigObject.timeoutIntervalForResource = 10.0;
    defaultConfigObject.requestCachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;

    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue: [NSOperationQueue mainQueue]];

    NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:headRequest
        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
    {
        if (!error && response)
        {
            block([(NSHTTPURLResponse *)response statusCode] == 200);
        }
    }];
    [dataTask resume];
}

- (void)yourMethod
{
    [self checkInternet:^(BOOL internet)
    {
         if (internet)
         {
             // "Internet" aka Google URL reachable
         }
         else
         {
             // No "Internet" aka Google URL un-reachable
         }
    }];
}
klcjr89
quelle
3
Scheint, als wäre dies der schnellste Weg
Pavel
3
Achtung: Nach meiner Erfahrung funktioniert diese Lösung nicht immer. In vielen Fällen ist die zurückgegebene Antwort 403, nachdem sie sich die Zeit genommen hat. Diese Lösung schien perfekt zu sein, garantiert jedoch keine 100% igen Ergebnisse.
Mustafa
10
Ab Juni 2014 wird dies auf dem chinesischen Festland fehlschlagen, da die chinesische Regierung google.com jetzt vollständig blockiert. (google.cn funktioniert zwar, aber auf dem chinesischen Festland kein baidu.com, kein Internet) Wahrscheinlich ist es besser, den Server anzupingen, mit dem Sie kommunizieren müssen.
Prewett
4
Verwenden Sie stattdessen www.appleiphonecell.com - Apple hat diese URL genau aus diesem Grund erstellt.
Smikey
1
Ich habe Appleiphonecell verwendet, da es Apples eigenes ist, auch in China verwendet werden kann und es eine sehr schnelle Website ist. In Verbindung mit Ihrer Antwort erhielt ich die nächstgelegene und schnellste Lösung. Vielen Dank
Septronic
57

Apple liefert Beispielcode , um nach verschiedenen Arten der Netzwerkverfügbarkeit zu suchen. Alternativ gibt es ein Beispiel im Kochbuch der iPhone-Entwickler.

Hinweis: Bitte beachten Sie den Kommentar von @ KHG zu dieser Antwort bezüglich der Verwendung des Erreichbarkeitscodes von Apple.

Teabot
quelle
Vielen Dank. Ich habe festgestellt, dass die Xcode-Dokumentation in 3.0 auch den Quellcode enthält, der durch Suchen nach "Erreichbarkeit" in der Dokumentation gefunden wurde.
Brock Woolf
7
Beachten Sie, dass die neue Version (09-08-09) des Reachability-Beispielcodes von Apple asynchron ist.
Daniel Hepper
46

Sie können Reachabilityvon  verwenden ( hier verfügbar ).

#import "Reachability.h"

- (BOOL)networkConnection {
    return [[Reachability reachabilityWithHostName:@"www.google.com"] currentReachabilityStatus];
}

if ([self networkConnection] == NotReachable) { /* No Network */ } else { /* Network */ } //Use ReachableViaWiFi / ReachableViaWWAN to get the type of connection.
Aleksander Azizi
quelle
@ Supertecnoboff Nein, es ist asynchron.
Aleksander Azizi
39

Apple bietet eine Beispiel-App, die genau dies tut:

Erreichbarkeit

NANNAV
quelle
7
Sie sollten beachten, dass das Reachability-Beispiel nur erkennt, welche Schnittstellen aktiv sind, nicht jedoch welche eine gültige Verbindung zum Internet haben. Anwendungen sollten Fehler auch dann ordnungsgemäß behandeln, wenn Reachability meldet, dass alles betriebsbereit ist.
rpetrich
Glücklicherweise ist die Situation in 3.0 viel besser, da das System eine Anmeldeseite für Benutzer hinter einem gesperrten WLAN anzeigt, auf der Sie sich anmelden müssen, um zu verwenden ... Sie müssen manuell nach der Weiterleitung suchen (und das tun Sie immer noch) bei der Entwicklung von 2.2.1 Apps)
Kendall Helmstetter Gelner
Ich würde nicht sagen, dass die Reachability-App genau das tut, wonach sie gefragt ist. Es ist jedoch ein guter Ausgangspunkt, um die Art von Funktionalität hinzuzufügen, die benötigt wird
Johan Karlsson
Defekter Link!, Würde mich freuen, wenn dies überprüft / behoben werden kann, vielen Dank
Heider Sati
33

Nur die Erreichbarkeitsklasse wurde aktualisiert. Sie können jetzt verwenden:

Reachability* reachability = [Reachability reachabilityWithHostName:@"www.apple.com"];
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

if (remoteHostStatus == NotReachable) { NSLog(@"not reachable");}
else if (remoteHostStatus == ReachableViaWWAN) { NSLog(@"reachable via wwan");}
else if (remoteHostStatus == ReachableViaWiFi) { NSLog(@"reachable via wifi");}
Ben Groot
quelle
1
Sofern sich seit der Veröffentlichung von 4.0 nichts geändert hat, ist dieser Code nicht asynchron und Sie werden garantiert in Crash Reports angezeigt - ist mir schon einmal passiert.
Papa
1
Ich stimme bpapa zu. Es ist keine gute Idee, synchronen Code zu verwenden. Vielen Dank für die Info
Brock Woolf
25

Hier gibt es eine gut aussehende, ARC- und GCD-verwendende Modernisierung der Erreichbarkeit:

Erreichbarkeit

JK Laiho
quelle
22

Wenn Sie verwenden AFNetworking, können Sie eine eigene Implementierung für den Status der Internet-Erreichbarkeit verwenden.

Am besten verwenden Sie AFNetworkingdie AFHTTPClientKlasse in Unterklassen und verwenden diese Klasse, um Ihre Netzwerkverbindungen herzustellen.

Einer der Vorteile dieses Ansatzes besteht darin, dass Sie blocksdas gewünschte Verhalten festlegen können, wenn sich der Erreichbarkeitsstatus ändert. Angenommen, ich habe eine Singleton-Unterklasse mit dem Namen AFHTTPClient(wie in den "Unterklassennotizen" in AFNetworking-Dokumenten angegeben )) erstellt BKHTTPClient, würde ich Folgendes tun:

BKHTTPClient *httpClient = [BKHTTPClient sharedClient];
[httpClient setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)
{
    if (status == AFNetworkReachabilityStatusNotReachable) 
    {
    // Not reachable
    }
    else
    {
        // Reachable
    }
}];

Sie können auch mithilfe von AFNetworkReachabilityStatusReachableViaWWANund AFNetworkReachabilityStatusReachableViaWiFienums nach Wi-Fi- oder WLAN-Verbindungen suchen ( mehr hier ).

Bruno Koga
quelle
18

Ich habe den Code in dieser Diskussion verwendet und er scheint gut zu funktionieren (lesen Sie den gesamten Thread!).

Ich habe es nicht mit jeder denkbaren Art von Verbindung (wie Ad-hoc-WLAN) ausführlich getestet.

Felixyz
quelle
Dieser Code ist nicht ganz gut, da er nur prüft, ob Sie eine WLAN-Verbindung mit einem Router haben und nicht, ob das Web erreichbar ist. Sie können WLAN verwenden und weiterhin aktivieren, um das Web zu erreichen.
DuckDucking
15

Sehr einfach .... Versuchen Sie diese Schritte:

Schritt 1: Fügen Sie das SystemConfigurationFramework zu Ihrem Projekt hinzu.


Schritt 2: Importieren Sie den folgenden Code in Ihre headerDatei.

#import <SystemConfiguration/SystemConfiguration.h>

Schritt 3: Verwenden Sie die folgende Methode

  • Typ 1:

    - (BOOL) currentNetworkStatus {
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        BOOL connected;
        BOOL isConnected;
        const char *host = "www.apple.com";
        SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, host);
        SCNetworkReachabilityFlags flags;
        connected = SCNetworkReachabilityGetFlags(reachability, &flags);
        isConnected = NO;
        isConnected = connected && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired);
        CFRelease(reachability);
        return isConnected;
    }

  • Typ 2:

    Header importieren :#import "Reachability.h"

    - (BOOL)currentNetworkStatus
    {
        Reachability *reachability = [Reachability reachabilityForInternetConnection];
        NetworkStatus networkStatus = [reachability currentReachabilityStatus];
        return networkStatus != NotReachable;
    }

Schritt 4: Verwendung:

- (void)CheckInternet
{
    BOOL network = [self currentNetworkStatus];
    if (network)
    {
        NSLog(@"Network Available");
    }
    else
    {
        NSLog(@"No Network Available");
    }
}
Rajesh Loganathan
quelle
Ist Typ 1 asynchron?
Supertecnoboff
Ich möchte die Typ-2-Korrekturen aus Ihrer Antwort. Ich habe die Erreichbarkeitsklassen hinzugefügt und versucht, die Verbindungsüberprüfung anhand der obigen Antwort zu überprüfen. Es ist immer erreichbar, auch wenn ich eine Verbindung mit WiFi herstelle, aber keine Internetverbindung hat. WiFi bedeutet nicht, dass es eine Internetverbindung hat. Ich möchte die Internetverbindung überprüfen, auch wenn sie über eine WiFi-Verbindung verfügt. Können Sie mir bitte helfen?
Wesley
12
-(void)newtworkType {

 NSArray *subviews = [[[[UIApplication sharedApplication] valueForKey:@"statusBar"] valueForKey:@"foregroundView"]subviews];
NSNumber *dataNetworkItemView = nil;

for (id subview in subviews) {
    if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) {
        dataNetworkItemView = subview;
        break;
    }
}


switch ([[dataNetworkItemView valueForKey:@"dataNetworkType"]integerValue]) {
    case 0:
        NSLog(@"No wifi or cellular");
        break;

    case 1:
        NSLog(@"2G");
        break;

    case 2:
        NSLog(@"3G");
        break;

    case 3:
        NSLog(@"4G");
        break;

    case 4:
        NSLog(@"LTE");
        break;

    case 5:
        NSLog(@"Wifi");
        break;


    default:
        break;
}
}
Mutawe
quelle
7
Selbst wenn das Gerät mit Wifi oder einem anderen Netzwerktyp verbunden ist, ist die Internetverbindung möglicherweise nicht verfügbar. Einfacher Test: Stellen Sie eine Verbindung zu Ihrem Heim-WLAN her und ziehen Sie dann den Stecker aus der Steckdose. Immer noch mit WLAN verbunden, aber kein Internet.
Ich wurde
11
- (void)viewWillAppear:(BOOL)animated
{
    NSString *URL = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];

    return (URL != NULL ) ? YES : NO;
}

Oder verwenden Sie die Erreichbarkeitsklasse .

Es gibt zwei Möglichkeiten, die Internetverfügbarkeit mithilfe des iPhone SDK zu überprüfen:

1. Überprüfen Sie, ob die Google-Seite geöffnet ist oder nicht.

2. Erreichbarkeitsklasse

Weitere Informationen finden Sie unter Erreichbarkeit (Apple Developer).

IOS Rocks
quelle
1
Es gibt zwei Möglichkeiten, die Internetverfügbarkeit im iPhone SDK zu überprüfen: 1) Überprüfen Sie, ob die Google-Seite geöffnet ist oder nicht.
IOS Rocks
1
-1: Dies ist eine synchrone Methode, die den Hauptthread blockiert (den, auf dem die App-Benutzeroberfläche geändert wird), während versucht wird, eine Verbindung zu google.com herzustellen. Wenn Ihr Benutzer eine sehr langsame Datenverbindung hat, verhält sich das Telefon so, als würde der Vorgang nicht reagieren.
Ich wurde am
10

Verwenden Sie http://huytd.github.io/datatify/ . Es ist einfacher als Bibliotheken hinzuzufügen und Code selbst zu schreiben.

Huy Tran
quelle
10

Erstens : CFNetwork.frameworkIm Framework hinzufügen

Code :ViewController.m

#import "Reachability.h"

- (void)viewWillAppear:(BOOL)animated
{
    Reachability *r = [Reachability reachabilityWithHostName:@"www.google.com"];
    NetworkStatus internetStatus = [r currentReachabilityStatus];

    if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
    {
        /// Create an alert if connection doesn't work
        UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle:@"No Internet Connection"   message:NSLocalizedString(@"InternetMessage", nil)delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [myAlert show];
        [myAlert release];
    }
    else
    {
         NSLog(@"INTERNET IS CONNECT");
    }
}
Paresh Hirpara
quelle
8

Laden Sie zuerst die Erreichbarkeitsklasse herunter und fügen Sie die Dateienieldability.h und Reachabilty.m in Ihren Xcode ein .

Der beste Weg ist, eine gemeinsame Funktionsklasse (NSObject) zu erstellen, damit Sie sie für jede Klasse verwenden können. Dies sind zwei Methoden für eine Überprüfung der Erreichbarkeit der Netzwerkverbindung:

+(BOOL) reachabiltyCheck
{
    NSLog(@"reachabiltyCheck");
    BOOL status =YES;
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(reachabilityChanged:)
                                          name:kReachabilityChangedNotification
                                          object:nil];
    Reachability * reach = [Reachability reachabilityForInternetConnection];
    NSLog(@"status : %d",[reach currentReachabilityStatus]);
    if([reach currentReachabilityStatus]==0)
    {
        status = NO;
        NSLog(@"network not connected");
    }
    reach.reachableBlock = ^(Reachability * reachability)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
        });
    };
    reach.unreachableBlock = ^(Reachability * reachability)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
        });
    };
    [reach startNotifier];
    return status;
}

+(BOOL)reachabilityChanged:(NSNotification*)note
{
    BOOL status =YES;
    NSLog(@"reachabilityChanged");
    Reachability * reach = [note object];
    NetworkStatus netStatus = [reach currentReachabilityStatus];
    switch (netStatus)
    {
        case NotReachable:
            {
                status = NO;
                NSLog(@"Not Reachable");
            }
            break;

        default:
            {
                if (!isSyncingReportPulseFlag)
                {
                    status = YES;
                    isSyncingReportPulseFlag = TRUE;
                    [DatabaseHandler checkForFailedReportStatusAndReSync];
                }
            }
            break;
    }
    return status;
}

+ (BOOL) connectedToNetwork
{
    // Create zero addy
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;

    // Recover reachability flags
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;
    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);
    if (!didRetrieveFlags)
    {
        NSLog(@"Error. Could not recover network reachability flags");
        return NO;
    }
    BOOL isReachable = flags & kSCNetworkFlagsReachable;
    BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
    BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
    NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"];
    NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL  cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
    NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];
    return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
}

Jetzt können Sie die Netzwerkverbindung in jeder Klasse überprüfen, indem Sie diese Klassenmethode aufrufen.

Latika Tiwari
quelle
8

Es gibt auch eine andere Methode, um die Internetverbindung mit dem iPhone SDK zu überprüfen.

Versuchen Sie, den folgenden Code für die Netzwerkverbindung zu implementieren.

#import <SystemConfiguration/SystemConfiguration.h>
#include <netdb.h>

/**
     Checking for network availability. It returns
     YES if the network is available.
*/
+ (BOOL) connectedToNetwork
{

    // Create zero addy
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;

    // Recover reachability flags
    SCNetworkReachabilityRef defaultRouteReachability =
        SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;

    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);

    if (!didRetrieveFlags)
    {
        printf("Error. Could not recover network reachability flags\n");
        return NO;
    }

    BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0);
    BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0);

    return (isReachable && !needsConnection) ? YES : NO;
}
Sahil Mahajan
quelle
8
  1. Laden Sie die Erreichbarkeitsdatei unter https://gist.github.com/darkseed/1182373 herunter

  2. Und fügen Sie CFNetwork.frameworkund 'SystemConfiguration.framework' im Framework hinzu

  3. Führen Sie #import "Reachability.h" aus


Erstens : CFNetwork.frameworkIm Framework hinzufügen

Code :ViewController.m

- (void)viewWillAppear:(BOOL)animated
{
    Reachability *r = [Reachability reachabilityWithHostName:@"www.google.com"];
    NetworkStatus internetStatus = [r currentReachabilityStatus];

    if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
    {
        /// Create an alert if connection doesn't work
        UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle:@"No Internet Connection"   message:NSLocalizedString(@"InternetMessage", nil)delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [myAlert show];
        [myAlert release];
    }
    else
    {
         NSLog(@"INTERNET IS CONNECT");
    }
}
Maulik Salvi
quelle
8

Swift 3 / Swift 4

Sie müssen zuerst importieren

import SystemConfiguration

Sie können die Internetverbindung mit der folgenden Methode überprüfen

func isConnectedToNetwork() -> Bool {

    var zeroAddress = sockaddr_in()
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)

    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
        }
    }

    var flags = SCNetworkReachabilityFlags()
    if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
        return false
    }
    let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
    let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
    return (isReachable && !needsConnection)

}
Devang Tandel
quelle
7

Die Erreichbarkeitsklasse ist in Ordnung, um herauszufinden, ob die Internetverbindung für ein Gerät verfügbar ist oder nicht ...

Aber beim Zugriff auf eine Intranet-Ressource :

Das Pingen des Intranetservers mit der Erreichbarkeitsklasse gibt immer true zurück.

Eine schnelle Lösung in diesem Szenario wäre daher, eine pingmeWebmethode zu erstellen, die zusammen mit anderen Webmethoden im Dienst aufgerufen wird. Das pingmesollte etwas zurückgeben.

Also habe ich die folgende Methode über allgemeine Funktionen geschrieben

-(BOOL)PingServiceServer
{
    NSURL *url=[NSURL URLWithString:@"http://www.serveraddress/service.asmx/Ping"];

    NSMutableURLRequest *urlReq=[NSMutableURLRequest requestWithURL:url];

    [urlReq setTimeoutInterval:10];

    NSURLResponse *response;

    NSError *error = nil;

    NSData *receivedData = [NSURLConnection sendSynchronousRequest:urlReq
                                                 returningResponse:&response
                                                             error:&error];
    NSLog(@"receivedData:%@",receivedData);

    if (receivedData !=nil)
    {
        return YES;
    }
    else
    {
        NSLog(@"Data is null");
        return NO;
    }
}

Die obige Methode war für mich sehr nützlich. Wenn ich versuche, Daten an den Server zu senden, überprüfe ich immer die Erreichbarkeit meiner Intranet-Ressource mithilfe dieser URLRequest mit geringem Zeitlimit.

Durai Amuthan.H
quelle
7

Dies selbst zu tun ist extrem einfach. Die folgende Methode funktioniert. Stellen Sie nur sicher, dass ein Hostnamenprotokoll wie HTTP, HTTPS usw. nicht mit dem Namen übergeben wird.

-(BOOL)hasInternetConnection:(NSString*)urlAddress
{
    SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [urlAddress UTF8String]);
    SCNetworkReachabilityFlags flags;
    if (!SCNetworkReachabilityGetFlags(ref, &flags))
    {
        return NO;
    }
    return flags & kSCNetworkReachabilityFlagsReachable;
}

Es ist schnell, einfach und schmerzlos.

Tony
quelle
7

Ich denke, das ist die beste Antwort.

"Ja" bedeutet verbunden. "Nein" bedeutet getrennt.

#import "Reachability.h"

 - (BOOL)canAccessInternet
{
    Reachability *IsReachable = [Reachability reachabilityForInternetConnection];
    NetworkStatus internetStats = [IsReachable currentReachabilityStatus];

    if (internetStats == NotReachable)
    {
        return NO;
    }
    else
    {
        return YES;
    }
}
Mina Fawzy
quelle
6

Importieren Sie die Reachable.hKlasse in Ihre ViewControllerund verwenden Sie den folgenden Code, um die Konnektivität zu überprüfen :

     #define hasInternetConnection [[Reachability reachabilityForInternetConnection] isReachable]
     if (hasInternetConnection){
           // To-do block
     }
Himanshu Mahajan
quelle
Ihre Antwort ist genau das, wonach ich suche. Ihr Herr verdient eine Abstimmung xD
Nikel Arteta
Funktioniert nicht, wenn Sie ohne Internet mit einem WLAN verbunden sind.
Keselme
6
  • Schritt 1: Fügen Sie die Erreichbarkeitsklasse in Ihr Projekt ein.
  • Schritt 2: Importieren Sie die Erreichbarkeitsklasse
  • Schritt 3: Erstellen Sie die folgende Funktion

    - (BOOL)checkNetConnection {
        self.internetReachability = [Reachability reachabilityForInternetConnection];
        [self.internetReachability startNotifier];
        NetworkStatus netStatus = [self.internetReachability currentReachabilityStatus];
        switch (netStatus) {
            case NotReachable:
            {
                return NO;
            }
    
            case ReachableViaWWAN:
            {
                 return YES;
            }
    
            case ReachableViaWiFi:
            {
                 return YES;
            }
        }
    }
  • Schritt 4: Rufen Sie die Funktion wie folgt auf:

    if (![self checkNetConnection]) {
        [GlobalFunctions showAlert:@""
                         message:@"Please connect to the Internet!"
                         canBtntitle:nil
                         otherBtnTitle:@"Ok"];
        return;
    }
    else
    {
        Log.v("internet is connected","ok");
    }
Anny
quelle
In den Apple-Dokumenten heißt es : Hinweis: Die Erreichbarkeit kann Ihrer Anwendung nicht mitteilen, ob Sie eine Verbindung zu einem bestimmten Host herstellen können, sondern nur, dass eine Schnittstelle verfügbar ist, die möglicherweise eine Verbindung zulässt, und ob es sich bei dieser Schnittstelle um den WWAN handelt.
Noobsmcgoobs