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

1326

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

J'ai trouvé un moyen de le faire en utilisant un NSURL. La façon dont je l'ai fait semble un peu peu fiable (car même Google pourrait un jour être en panne et s'appuyer sur un tiers semble mauvais), et même si je pouvais vérifier pour voir une réponse de certains autres sites Web si Google ne répondait pas, il ne semble gaspillage et une surcharge inutile sur 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 agi (sans parler de la stringWithContentsOfURLdépréciation dans iOS 3.0 et macOS 10.4) et si oui, quelle est la meilleure façon d'y parvenir?

Brock Woolf
la source
11
Plutôt return (BOOL)URLString;, ou encore mieux, return !!URLStringoureturn URLString != nil
3
Je ne sais pas quel est votre cas d'utilisation, mais si vous le pouvez, il est préférable d'essayer la demande et de gérer les erreurs telles qu'un manque de connexion qui survient. Si vous ne pouvez pas faire cela, alors il y a beaucoup de bons conseils ici dans ce cas.
SK9
2
Votre solution est intelligente et je la préfère. Vous pouvez également utiliser NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://twitter.com/getibox"] encoding:NSUTF8StringEncoding error:nil];Pour se débarrasser de l'avertissement ennuyeux.
Abdelrahman Eid
4
essayez d'utiliser la classe d'accessibilité à partir du lien ci-dessous, cela fonctionnera pour vous github.com/tonymillion/Reachability
Dhaval H. Nena
4
Pour ceux qui ont récemment trouvé cette réponse: stackoverflow.com/a/8813279
afollestad

Réponses:

1285

Important : cette vérification doit toujours être effectuée de manière asynchrone. La majorité des réponses ci-dessous sont synchrones, alors faites attention sinon vous ferez geler votre application.


Rapide

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

2) Test d'accessibilité via les 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) Ajoutez un SystemConfigurationcadre au projet mais ne vous inquiétez pas de l'inclure n'importe où

2) Ajoutez la version de Tony Million de Reachability.het Reachability.mau projet (disponible ici: https://github.com/tonymillion/Reachability )

3) Mettre à jour la section 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];
}

Remarque importante: la Reachabilityclasse est l'une des classes les plus utilisées dans les projets, vous pouvez donc rencontrer des conflits de dénomination avec d'autres projets. Si cela se produit, vous devrez renommer l'une des paires de fichiers Reachability.het Reachability.men quelque chose d'autre pour résoudre le problème.

Remarque: le domaine que vous utilisez n'a pas d'importance. Il s'agit simplement de tester une passerelle vers n'importe quel domaine.

J'ai été volé
la source
4
@gonzobrains: Le domaine que vous utilisez n'a pas d'importance. Il s'agit simplement de tester une passerelle vers n'importe quel domaine.
iwasrobbed
3
@KaanDedeoglu Ce n'est qu'un exemple, utilisez le domaine de votre choix. Il vérifie simplement une passerelle vers Internet, pas que le domaine soit réellement disponible.
iwasrobbed
1
Oh, btw vous devez également ajouter SystemConfiguration.frameworkau projet (pour la méthode 1).
Windindy
2
Utilisez www.appleiphonecell.com au lieu de google.com - cette URL a été créée par Apple précisément pour cette raison.
Smikey
1
L'utilisation de www.appleiphonecell.com est désormais (2018) un mauvais choix. Il redirige maintenant vers Apple.com qui est un fichier html> 40 Ko. Revenons à google.com - il ne fait que 11 Ko. BTW google.com/m a la même taille mais serait plus lent de 120 ms.
BlueskyMed
311

J'aime garder les choses simples. La façon dont je fais cela 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, j'utilise ceci 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 états de réseau modifiés pour faire des choses. Il teste simplement le statut lorsque vous le lui demandez.

cannyboy
la source
Salut @msec, vous pouvez essayer la solution Andrew Zimmer dans cette page, cela fonctionne très bien avec adsl déconnecté (et wifi connecté)
Williew
1
Pour ceux qui viennent de copier et coller comme je l'ai fait avec le code ci-dessus. Ajoutez également SystemConfiguration.framework manuellement ou vous obtiendrez une erreur de liaison.
Iftikhar Ali Ansari
Toujours aussi accessible si je me connecte avec le WiFi. Le WiFi ne signifie pas qu'il dispose d'une connexion Internet. Je veux vérifier la connexion Internet même si elle a une connectivité WiFi. Pouvez vous me donner un coup de main?
wesley
@wesley Comment l'avez-vous résolu?
Keselme
146

En utilisant le code d'accessibilité d'Apple, j'ai créé une fonction qui vérifiera cela correctement sans que vous ayez à 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 c'est iOS 5 testé pour vous.

Andrew Zimmer
la source
@JezenThomas Cela n'effectue pas la vérification Internet de manière asynchrone, c'est pourquoi il est "beaucoup plus mince" ... Vous devriez toujours le faire de manière asynchrone en vous abonnant aux notifications afin de ne pas raccrocher l'application sur ce processus.
iwasrobbed
Merci, ce travail même si vous utilisez le wifi adsl et adsl n'est pas connecté, c'est exactement ce dont j'ai besoin.
Williew
5
Cela fuit la mémoire - la structure de «lisibilité» (objet, chose) doit être libérée avec CFRelease ().
Russell Mull
@RussellMull ... une idée de comment réparer la fuite?
i_raqz
Bizarre que cette réponse soit antérieure à la mienne (sur une question marquée comme doublon) de 2 ans, est exactement la même que la mienne, mais je ne l'ai jamais vue jusqu'à aujourd'hui.
ArtOfWarfare
122

Auparavant, c'était la bonne réponse, mais elle est désormais obsolète car vous devez vous abonner aux notifications pour être joignable à la place. Cette méthode vérifie de manière synchrone:


Vous pouvez utiliser la classe d'accessibilité d'Apple. Il 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 d'accessibilité n'est pas fournie avec le SDK, mais plutôt une partie de cet exemple d'application Apple . Téléchargez-le et copiez Reachability.h / m dans votre projet. Vous devez également ajouter le framework SystemConfiguration à votre projet.

Daniel Rinser
la source
6
Voir mon commentaire ci-dessus à propos de ne pas utiliser l'accessibilité comme ça. Utilisez-le en mode asynchrone et abonnez-vous aux notifications qu'il envoie - ne le faites pas.
Kendall Helmstetter Gelner
Ce code est un bon point de départ pour les choses que vous devez définir avant de pouvoir utiliser les méthodes déléguées pour la classe d'accessibilité.
Brock Woolf
82

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 téléchargerais un petit fichier avec un seul caractère pour une vitesse maximale.

Si vérifier que l'appareil est connecté d'une manière ou d'une autre à 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é, l'utilisation de l'accessibilité 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 en tenir compte (merci à Brad pour l'avoir signalé).

Erik
la source
10
J'aime vraiment cette idée, mais je dirais que pour la fiabilité de 99,999% tout en conservant une petite taille de réponse, rendez-vous sur www.google.com/m qui est la vue mobile pour google.
rwyland
1
Super solution @Erik. Ce que je vous recommande également, c'est d'utiliser www.google.com, au lieu de www.google.com/m, comme l'a dit rwyland. C'est bizarre, mais d'après mon test, la version mobile prend toujours environ 120 ms de plus que www.google.com
Sebyddd
4
Les documents Apple recommandent de ne pas le faire car cela peut bloquer le fil sur un réseau lent, peut entraîner la fermeture de l'application dans iOS
Brad Thomas
Merci pour les commentaires positifs, convenez que www.google.com/m est la meilleure solution en raison de la fiabilité!
Erik
3
LOL, je suis sûr que Google apprécie que vous suggériez aux gens de les utiliser comme ressource de vérification Internet.
mxcl
73

Voici comment je le fais dans mes applications: bien qu'un code de réponse à 200 états ne garantisse rien, il est suffisamment stable pour moi. Cela ne nécessite pas autant de chargement que les réponses NSData publié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.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
        }
    })
}

Code Objective-C

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
la source
3
On dirait que c'est le moyen le plus rapide
Pavel
3
Attention: D'après mon expérience, cette solution ne fonctionne pas tout le temps. Dans de nombreux cas, la réponse renvoyée est 403, après avoir pris son temps doux. Cette solution semblait parfaite, mais ne garantit pas des résultats à 100%.
Mustafa
10
En juin 2014, cela échouera en Chine continentale, le gouvernement chinois bloquant désormais complètement google.com. (google.cn fonctionne, cependant, mais en Chine continentale, pas de baidu.com, pas d'Internet) Probablement mieux d'envoyer une requête ping au serveur avec lequel vous devez communiquer.
prewett
4
Utilisez plutôt www.appleiphonecell.com - Apple a créé cette URL précisément pour cette raison.
Smikey
1
J'ai utilisé appleiphonecell comme c'est le cas d'Apple, peut également être utilisé en Chine, et c'est un site très rapide. Ceci, conjointement avec votre réponse, m'a fourni la solution la plus proche et la plus rapide. Merci
Septronic
57

Apple fournit un exemple de code pour vérifier les différents types de disponibilité du réseau. Alternativement, il y a un exemple dans le livre de cuisine des développeurs iPhone.

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

théière
la source
Merci. J'ai découvert que la documentation Xcode dans 3.0 contient également le code source, trouvé en recherchant "accessibilité" dans la documentation.
Brock Woolf
7
Notez que la nouvelle révision (09-08-09) de l'exemple de code d'accessibilité d'Apple est asynchrone.
Daniel Hepper
46

Vous pouvez utiliser Reachabilitypar  ( 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.
Aleksander Azizi
la source
@Supertecnoboff Non, c'est asynchrone.
Aleksander Azizi
39

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

Accessibilité

NANNAV
la source
7
Vous devez noter que l'exemple d'accessibilité détecte uniquement les interfaces actives, mais pas celles qui ont une connexion valide à Internet. Les applications doivent gérer correctement les échecs même lorsque Reachability signale que tout est prêt.
rpetrich
Heureusement, la situation est bien meilleure dans 3.0, car le système présentera une page de connexion pour les utilisateurs derrière un WiFi verrouillé où vous devez vous connecter pour utiliser ... vous devez avoir à vérifier manuellement la redirection (et vous le faites toujours si vous développez des applications 2.2.1)
Kendall Helmstetter Gelner
Je ne dirais pas que l'application Reachability fait exactement ce qui est demandé. Cependant, c'est un bon point de départ pour ajouter le type de fonctionnalité demandé,
Johan Karlsson
Lien brisé !, apprécierait que cela puisse être vérifié / corrigé, merci beaucoup
Heider Sati
33

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");}
Ben Groot
la source
1
Sauf si quelque chose a changé depuis la sortie de la version 4.0, ce code n'est pas asynchrone et vous êtes assuré de le voir apparaître dans Crash Reports - ce qui m'est déjà arrivé.
bpapa
1
Je suis d'accord avec bpapa. Ce n'est pas une bonne idée d'utiliser du code synchrone. Merci pour l'info
Brock Woolf
25

Il y a une belle modernisation de l'accessibilité utilisant ARC et GCD:

Accessibilité

JK Laiho
la source
22

Si vous utilisez, AFNetworkingvous pouvez utiliser sa propre implémentation pour le statut d'accessibilité à Internet.

La meilleure façon d'utiliser AFNetworkingest de sous- AFHTTPClientclasser la classe et d'utiliser cette classe pour effectuer vos connexions réseau.

L'un des avantages de cette approche est que vous pouvez l'utiliser blockspour définir le comportement souhaité lorsque l'état de l'accessibilité change. En supposant que j'ai créé une sous-classe singleton de AFHTTPClient(comme indiqué dans les "Notes de sous-classe" sur les documents AFNetworking ) nommée BKHTTPClient, je ferais quelque chose comme:

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

Vous pouvez également vérifier les connexions Wi-Fi ou WLAN en utilisant spécifiquement les enums AFNetworkReachabilityStatusReachableViaWWANet AFNetworkReachabilityStatusReachableViaWiFi( plus ici ).

Bruno Koga
la source
18

J'ai utilisé le code dans cette discussion , et il semble bien fonctionner (lire tout le fil!).

Je ne l'ai pas testé de manière exhaustive avec tous les types de connexion imaginables (comme le Wi-Fi ad hoc).

Felixyz
la source
ce code n'est pas totalement bon car il vérifie juste si vous avez une connexion wifi avec un routeur, pas si le web est accessible. Vous pouvez faire fonctionner le wifi et continuer à l'activer pour accéder au Web.
DuckDucking
15

Très simple .... Essayez ces étapes:

Étape 1: ajoutez le SystemConfigurationcadre à votre projet.


Étape 2: importez le code suivant dans votre headerfichier.

#import <SystemConfiguration/SystemConfiguration.h>

Étape 3: utilisez la méthode suivante

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

  • Type 2:

    Importer l'en-tête :#import "Reachability.h"

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

Étape 4: Comment utiliser:

- (void)CheckInternet
{
    BOOL network = [self currentNetworkStatus];
    if (network)
    {
        NSLog(@"Network Available");
    }
    else
    {
        NSLog(@"No Network Available");
    }
}
Rajesh Loganathan
la source
Le type 1 est-il asynchrone?
Supertecnoboff
Je veux les correctifs de type 2 de votre réponse. J'ai ajouté les classes d'accessibilité et j'ai essayé de vérifier la vérification de la connexion en utilisant ci-dessus votre réponse. il est toujours accessible même si je me connecte avec le WiFi mais il n'a pas de connexion Internet. Le WiFi ne signifie pas qu'il dispose d'une connexion Internet. Je veux vérifier la connexion Internet même si elle a une connectivité WiFi. Pouvez vous me donner un coup de main?
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
la source
7
Même si l'appareil est connecté au Wifi ou à un autre type de réseau, la connexion Internet peut toujours être indisponible. Test simple: connectez-vous à votre wifi domestique puis débranchez votre modem câble. Toujours connecté au wifi, mais zéro internet.
iwasrobbed
11
- (void)viewWillAppear:(BOOL)animated
{
    NSString *URL = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];

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

Ou utilisez la classe d'accessibilité .

Il existe deux façons de vérifier la disponibilité d'Internet à l'aide du SDK iPhone:

1. Vérifiez que la page Google est ouverte ou non.

2. Classe d'accessibilité

Pour plus d'informations, reportez-vous à la section Accessibilité (développeur Apple).

IOS Rocks
la source
1
Il existe deux façons de vérifier la disponibilité d'Internet dans le SDK iPhone 1) Vérifiez que la page Google est ouverte ou non.
IOS Rocks
1
-1: Il s'agit d'une méthode synchrone qui bloquera le thread principal (celui sur lequel l'interface utilisateur de l'application est modifiée) pendant qu'il essaie de se connecter à google.com. Si votre utilisateur utilise une connexion de données très lente, le téléphone agira comme si le processus ne répond pas.
iwasrobbed
10

Utilisez http://huytd.github.io/datatify/ . C'est plus simple que d'ajouter des bibliothèques et d'écrire du code par vous-même.

Huy Tran
la source
10

Premièrement : ajouter CFNetwork.frameworkdans le cadre

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
la source
8

Téléchargez d'abord la classe d'accessibilité et mettez le fichier reachability.h et reachabilty.m dans votre Xcode .

La meilleure façon est de créer une classe Functions commune (NSObject) afin que vous puissiez l'utiliser dans n'importe quelle classe. Ce sont deux méthodes pour une vérification d'accessibilité de connexion réseau:

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

Vous pouvez maintenant vérifier la connexion réseau dans n'importe quelle classe en appelant cette méthode de classe.

Latika Tiwari
la source
8

Il existe également une autre méthode pour vérifier la connexion Internet à l'aide du SDK iPhone.

Essayez d'implémenter le code suivant pour la connexion réseau.

#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
la source
8
  1. Téléchargez le fichier d'accessibilité, https://gist.github.com/darkseed/1182373

  2. Et ajoutez CFNetwork.frameworket 'SystemConfiguration.framework' dans le cadre

  3. Faites #import "Reachability.h"


Premièrement : ajouter CFNetwork.frameworkdans le cadre

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
la source
8

Swift 3 / Swift 4

Vous devez d'abord importer

import SystemConfiguration

Vous pouvez vérifier la connexion Internet avec la méthode suivante

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
la source
7

La classe d'accessibilité est OK pour savoir si la connexion Internet est disponible ou non pour un appareil ...

Mais en cas d'accès à une ressource intranet :

Le ping du serveur intranet avec la classe d'accessibilité renvoie toujours true.

Ainsi, une solution rapide dans ce scénario serait de créer une méthode Web appelée pingmeavec d'autres méthodes Web sur le service. Le pingmedevrait retourner quelque chose.

J'ai donc écrit la méthode suivante sur les fonctions communes

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

La méthode ci-dessus m'a été si utile, donc chaque fois que j'essaie d'envoyer des données au serveur, je vérifie toujours l'accessibilité de ma ressource intranet à l'aide de cette URLRequest à faible délai d'attente.

Durai Amuthan.H
la source
7

Faire cela vous-même est extrêmement simple. La méthode suivante fonctionnera. Assurez-vous simplement de ne pas autoriser un protocole de nom d'hôte tel que HTTP, HTTPS, etc. avec le nom.

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

C'est simple, rapide et indolore.

Tony
la source
7

Je pense que celui-ci est la meilleure réponse.

"Oui" signifie connecté. "Non" signifie déconnecté.

#import "Reachability.h"

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

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

Importez la Reachable.hclasse dans votre ViewControlleret utilisez le code suivant pour vérifier la connectivité :

     #define hasInternetConnection [[Reachability reachabilityForInternetConnection] isReachable]
     if (hasInternetConnection){
           // To-do block
     }
Himanshu Mahajan
la source
Votre réponse est exactement ce que je recherche. Vous monsieur mérite un vote jusqu'à xD
Nikel Arteta
Ne fonctionne pas si vous êtes connecté à un réseau Wi-Fi sans Internet.
Keselme
6
  • Étape 1: ajoutez la classe d'accessibilité dans votre projet.
  • Étape 2: importez la classe d'accessibilité
  • Étape 3: créer la fonction ci-dessous

    - (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;
            }
        }
    }
  • Étape 4: appelez la fonction comme suit:

    if (![self checkNetConnection]) {
        [GlobalFunctions showAlert:@""
                         message:@"Please connect to the Internet!"
                         canBtntitle:nil
                         otherBtnTitle:@"Ok"];
        return;
    }
    else
    {
        Log.v("internet is connected","ok");
    }
Anny
la source
Les documents d'Apple indiquent ceci Remarque: l'accessibilité ne peut pas dire à votre application si vous pouvez vous connecter à un hôte particulier, seulement qu'une interface est disponible qui pourrait permettre une connexion, et si cette interface est le WWAN.
noobsmcgoobs