Frage Wie kann ich nach einer aktiven Internetverbindung auf iOS oder Mac OS suchen?


Ich möchte überprüfen, ob ich eine Internetverbindung auf iOS mit der Kakao-Touch Bibliotheken oder auf MacOS mit dem Kakao Bibliotheken.

Ich habe mir einen Weg ausgedacht, um dies mit einem NSURL. Die Art und Weise, wie ich es gemacht habe, scheint ein bisschen unzuverlässig zu sein (denn selbst Google könnte eines Tages ausfallen und sich auf einen Dritten verlassen scheint schlecht zu sein), und obwohl ich nach Antworten von anderen Webseiten sehen konnte, wenn Google nicht geantwortet hat scheint verschwenderisch und ein unnötiger Aufwand für meine Anwendung.

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

Ist, was ich schlecht gemacht habe (nicht zu erwähnen stringWithContentsOfURL ist in iOS 3.0 und MacOS 10.4 veraltet) und wenn ja, was ist ein besserer Weg, dies zu erreichen?


1223
2017-07-05 08:45


Ursprung


Antworten:


Wichtig: Dieser Check sollte immer asynchron durchgeführt werden. Die Mehrheit der Antworten unten ist synchron, also sei vorsichtig, sonst wirst du deine App einfrieren.


Schnell

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

2) Test Erreichbarkeit über Verschlüsse

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) Hinzufügen SystemConfiguration Rahmen für das Projekt, aber sorgen Sie sich nicht darum, es überall aufzunehmen

2) Füge Tony Million's Version hinzu Reachability.h und Reachability.m zum Projekt (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 der .m-Datei Ihres View-Controllers, den 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];
}

Wichtige Notiz: Das Reachability Klasse ist eine der am häufigsten verwendeten Klassen in Projekten, sodass Konflikte mit anderen Projekten auftreten können. In diesem Fall müssen Sie eines der beiden Paare umbenennen Reachability.h und Reachability.m Dateien zu etwas anderem, um das Problem zu lösen.

Hinweis: Die Domäne, die Sie verwenden, spielt keine Rolle. Es wird nur nach einem Gateway zu einer beliebigen Domäne gesucht.


1220
2017-08-29 23:58



Ich mag es, die Dinge einfach zu halten. Die Art, wie ich das mache ist:

//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 das immer wenn ich sehen will 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 etwas zu tun. Es testet nur den Status, wenn Sie es fragen.


303
2017-08-26 13:34



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

Fügen Sie das SystemConfiguration.framework in Ihrem 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 sein iOS 5 für dich getestet.


143
2017-10-28 20:37



Dies war früher die richtige Antwort, aber es ist jetzt veraltet, da Sie stattdessen Benachrichtigungen für die Erreichbarkeit abonnieren sollten. Diese Methode prüft synchron:


Sie können Apples Erreichbarkeitsklasse verwenden. Außerdem können Sie überprüfen, ob WLAN 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 ausgeliefert, sondern ein Teil davon diese Apple-Beispielanwendung. Laden Sie es einfach herunter und kopieren Sie Erreichbarkeit.h / m in Ihr Projekt. Außerdem müssen Sie das SystemConfiguration-Framework zu Ihrem Projekt hinzufügen.


118
2017-07-05 10:58



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 nutze die mobile Website von Google hier, aber wenn ich einen zuverlässigen Webserver hätte, würde ich ihn hochladen eine kleine Datei mit nur einem Zeichen für maximale Geschwindigkeit.

Wenn Sie überprüfen, ob das Gerät ist irgendwie verbunden mit dem Internet ist alles, was Sie tun möchten, würde ich definitiv diese einfache Lösung empfehlen. Wenn Sie wissen möchten, wie der Benutzer verbunden ist, ist die Verwendung von Erreichbarkeit der richtige Weg.

Vorsicht: Dies wird Ihren Thread während des Ladens der Website kurzzeitig blockieren. In meinem Fall war das kein Problem, aber Sie sollten darüber nachdenken (Credits an Brad, dass Sie darauf hingewiesen haben).


78
2018-05-14 22:25



Hier ist, wie ich es in meinen Apps mache: Während ein 200er Status-Response-Code nichts garantiert, ist er stabil genug für mich. Dies erfordert nicht so viel Laden wie die hier geposteten NSData-Antworten, da meine nur die HEAD-Antwort prüft.

SWIFT-Code

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

    let url = NSURL(string: "http://www.appleiphonecell.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 Apple's region universal URL reachable
        }
        else
        {
            // No "Internet" aka Apple's region universal URL un-reachable
        }
    })
}

Ziel-C-Code

typedef void(^connection)(BOOL);

- (void)checkInternet:(connection)block
{
    NSURL *url = [NSURL URLWithString:@"http://www.appleiphonecell.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 Apple's region universal URL reachable
         }
         else
         {
             // No "Internet" aka Apple's region universal URL un-reachable
         }
    }];
}

70
2017-11-30 03:26



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

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


54
2017-07-05 08:59