Question Comment vérifier une connexion Internet active sur iOS ou macOS?


Je voudrais vérifier pour voir si j'ai une connexion Internet sur iOS en utilisant le Cocoa Touch bibliothèques ou sur macOS en utilisant le Cacao bibliothèques.

Je suis venu avec un moyen de le faire en utilisant un NSURL. La façon dont je l'ai fait semble un peu peu fiable (parce que même Google pourrait un jour être en panne et compter sur un tiers semble mauvais), et pendant que je pourrais vérifier pour voir une réponse de certains autres sites si Google n'a pas répondu, Cela semble inutile et inutile pour ma demande.

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

Est-ce que j'ai mal fait (pour ne pas mentionner stringWithContentsOfURL est obsolète dans iOS 3.0 et macOS 10.4) et si oui, quel est le meilleur moyen d'y parvenir?


1223
2017-07-05 08:45


origine


Réponses:


Important: Ce chèque devrait toujours être effectué de manière asynchrone. La majorité des réponses ci-dessous sont synchrones, alors faites attention sinon vous allez geler votre application.


Rapide

1) Installer via CocoaPods ou Carthage: https://github.com/ashleymills/Reachability.swift

2) Test d'accessibilité via des fermetures

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

Objectif c

1) Ajouter SystemConfiguration cadre au projet, mais ne vous inquiétez pas de l'inclure partout

2) Ajouter la version de Tony Million de Reachability.h et Reachability.m au projet (trouvé ici: https://github.com/tonymillion/Reachability)

3) Mettre à jour la section d'interface

#import "Reachability.h"

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

4) Ensuite, implémentez cette méthode dans le fichier .m de votre contrôleur de vue que vous pouvez appeler

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

Note importante: le Reachability class est l'une des classes les plus utilisées dans les projets, vous risquez donc de rencontrer des conflits de noms avec d'autres projets. Si cela se produit, vous devrez renommer l'une des paires de Reachability.h et Reachability.m fichiers à quelque chose d'autre pour résoudre le problème.

Remarque: Le domaine que vous utilisez n'a pas d'importance. C'est juste de tester une passerelle vers n'importe quel domaine.


1220
2017-08-29 23:58



J'aime garder les choses simples. La façon dont je fais ceci est:

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

Ensuite, je l'utilise chaque fois que je veux voir si j'ai une connexion:

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

Cette méthode n'attend pas les statuts de réseau modifiés pour faire des choses. Il teste juste le statut quand vous le demandez.


303
2017-08-26 13:34



En utilisant le code d'accessibilité d'Apple, j'ai créé une fonction qui va vérifier cela correctement sans avoir à inclure de classes.

Incluez le SystemConfiguration.framework dans votre projet.

Faites quelques importations:

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

Appelez maintenant cette fonction:

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

Et son iOS 5 testé pour vous.


143
2017-10-28 20:37



Cette réponse était la bonne, mais elle est maintenant obsolète, car vous devriez vous abonner aux notifications d'accessibilité. Cette méthode vérifie de manière synchrone:


Vous pouvez utiliser la classe d'accessibilité d'Apple. Cela vous permettra également de vérifier si le Wi-Fi est activé:

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

La classe Reachability n'est pas fournie avec le SDK, mais plutôt une partie de cette application d'échantillon Apple. Il suffit de le télécharger et de copier Reachability.h / m dans votre projet. En outre, vous devez ajouter l'infrastructure SystemConfiguration à votre projet.


118
2017-07-05 10:58



Voici une réponse très simple:

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

L'URL doit pointer vers un site Web extrêmement petit. J'utilise le site Web mobile de Google ici, mais si j'avais un serveur web fiable, je le téléchargerais un petit fichier avec juste un caractère pour une vitesse maximale.

Si vous vérifiez si l'appareil est en quelque sorte connecté à Internet est tout ce que vous voulez faire, je recommanderais certainement d'utiliser cette solution simple. Si vous avez besoin de savoir comment l'utilisateur est connecté, utiliser Reachability est la solution.

Attention: Cela bloquera brièvement votre fil pendant qu'il charge le site Web. Dans mon cas, ce n'était pas un problème, mais vous devriez considérer ceci (les crédits à Brad pour le signaler).


78
2018-05-14 22:25



Voici comment je le fais dans mes applications: Alors qu'un code de réponse de 200 états ne garantit rien, il est assez stable pour moi. Cela ne nécessite pas autant de chargement que les réponses NSData affichées ici, car la mienne vérifie simplement la réponse HEAD.

Code rapide

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

Code Objective-C

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 fournitures exemple de code vérifier les différents types de disponibilité du réseau. Alternativement il y a un Exemple dans le livre de recettes des développeurs iPhone.

Remarque: Veuillez consulter le commentaire de @ KHG sur cette réponse concernant l'utilisation du code d'accessibilité d'Apple.


54
2017-07-05 08:59



Vous pourriez utiliser Reachability par  (disponible ici).

#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.

43
2018-04-25 12:20



Apple fournit un exemple d'application qui fait exactement cela:

Accessibilité


39
2017-07-05 08:58



Seule la classe d'accessibilité a été mise à jour. Vous pouvez maintenant utiliser:

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

32
2017-08-27 09:41



Une version sur Reachability pour iOS 5 est darkseed / Reachability.h. Ce n'est pas le mien! =)


27
2017-11-07 20:17