147 votes

Le moyen le plus simple de détecter la connexion Internet sur iOS ?

Je sais que cette question va sembler être une copie de beaucoup d'autres, cependant, je ne pense pas que le cas simple soit bien expliqué ici. Je viens d'un milieu Android et BlackBerry, faire des demandes par le biais de HTTPUrlConnection échoue instantanément s'il n'y a pas de connexion disponible. Cela semble être un comportement tout à fait sain, et j'ai été surpris de constater que NSURLConnection dans iOS ne l'a pas émulé.

J'ai cru comprendre qu'Apple (et d'autres qui l'ont étendu) fournit un service d'aide à l'emploi. Reachability pour aider à déterminer l'état du réseau. J'étais heureux de voir cela pour la première fois et je m'attendais à voir quelque chose comme bool isNetworkAvailable() Mais au lieu de cela, à ma grande surprise, j'ai trouvé un système complexe nécessitant des enregistrements de notifications et des rappels, ainsi qu'un tas de détails apparemment inutiles. Il doit y avoir une meilleure solution.

Mon application gère déjà gracieusement les échecs de connexion, y compris l'absence de connectivité. L'utilisateur est informé de l'échec et l'application poursuit son chemin.

Mes exigences sont donc simples : Une fonction unique et synchrone que je peux appeler avant toutes les requêtes HTTP pour déterminer si je dois prendre la peine d'envoyer la requête ou non. Idéalement, elle ne nécessite aucune configuration et renvoie simplement un booléen.

Est-ce que ce n'est vraiment pas possible sur iOS ?

250voto

Semere Taézaz Sium Points 2152

J'ai fait quelques recherches supplémentaires et je mets à jour ma réponse avec une solution plus actuelle. Je ne sais pas si vous avez déjà regardé, mais il y a un exemple de code fourni par Apple.

Télécharger l'exemple de code ici

Incluez les fichiers Reachability.h et Reachability.m dans votre projet. Jetez un coup d'oeil à ReachabilityAppDelegate.m pour voir un exemple sur la façon de déterminer l'accessibilité de l'hôte, l'accessibilité par WiFi, par WWAN, etc. Pour une vérification très simple de l'accessibilité du réseau, vous pouvez faire quelque chose comme ceci

Reachability *networkReachability = [Reachability reachabilityForInternetConnection];   
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];    
if (networkStatus == NotReachable) {        
    NSLog(@"There IS NO internet connection");        
} else {        
     NSLog(@"There IS internet connection");        
}

Celui de @BenjaminPiette : N'oubliez pas d'ajouter SystemConfiguration.framework à votre projet.

45voto

sherbertman Points 81

Étant donné que ce fil de discussion est le premier résultat de Google pour ce type de question, je me suis dit que j'allais fournir la solution qui a fonctionné pour moi. J'utilisais déjà AFNetworking mais la recherche n'a révélé comment accomplir cette tâche avec AFNetworking qu'au milieu de mon projet.

Ce que vous voulez, c'est le AFNetworkingReachabilityManager .

// -- Start monitoring network reachability (globally available) -- //
[[AFNetworkReachabilityManager sharedManager] startMonitoring];

[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {

    NSLog(@"Reachability changed: %@", AFStringFromNetworkReachabilityStatus(status));

    switch (status) {
        case AFNetworkReachabilityStatusReachableViaWWAN:
        case AFNetworkReachabilityStatusReachableViaWiFi:
            // -- Reachable -- //
            NSLog(@"Reachable");
            break;
        case AFNetworkReachabilityStatusNotReachable:
        default:
            // -- Not reachable -- //
            NSLog(@"Not Reachable");
            break;
    }

}];

Vous pouvez également utiliser ce qui suit pour tester l'accessibilité de manière synchrone (une fois que la surveillance a commencé) :

-(BOOL) isInternetReachable
{
    return [AFNetworkReachabilityManager sharedManager].reachable;
}

40voto

Ad-J Points 391

Désolé de répondre trop tard, mais j'espère que cette réponse pourra aider quelqu'un à l'avenir.

Voici un petit extrait de code C natif qui permet de vérifier la connectivité Internet sans aucune classe supplémentaire.

Ajoutez les en-têtes suivants :

#include<unistd.h>
#include<netdb.h>

Code :

-(BOOL)isNetworkAvailable
{
    char *hostname;
    struct hostent *hostinfo;
    hostname = "google.com";
    hostinfo = gethostbyname (hostname);
    if (hostinfo == NULL){
        NSLog(@"-> no connection!\n");
        return NO;
    }
    else{
        NSLog(@"-> connection established!\n");
        return YES;
    }
}

31voto

Gilesey Points 149

J'utilise actuellement cette méthode synchrone simple qui ne nécessite aucun fichier supplémentaire dans vos projets ou délégués.

Importation :

#import <SystemConfiguration/SCNetworkReachability.h>

Créez cette méthode :

-(bool)isNetworkAvailable
{
    SCNetworkReachabilityFlags flags;
    SCNetworkReachabilityRef address = SCNetworkReachabilityCreateWithName(NULL, "www.apple.com" );
    Boolean success = SCNetworkReachabilityGetFlags(address, &flags);
    CFRelease(address);

    bool canReachOnExistingConnection =     success
                                            && !(flags & kSCNetworkReachabilityFlagsConnectionRequired)
                                            && (flags & kSCNetworkReachabilityFlagsReachable);

    if( canReachOnExistingConnection )
        NSLog(@"Network available");
    else
        NSLog(@"Network not available");

    return canReachOnExistingConnection;
}

Si vous testez dans le simulateur, activez et désactivez le wifi de votre Mac, car il semble que le simulateur ignore le paramètre du téléphone.

11voto

danipralea Points 1185

C'est possible et c'est vraiment simple si vous regardez en finissant l'implémentation, qui est encore une fois - très simple, puisque les seuls éléments dont vous avez besoin sont deux variables booléennes : l'accessibilité à l'internet et l'accessibilité à l'hôte (vous avez souvent besoin de plus d'une de ces variables). Une fois que vous avez assemblé votre classe d'aide qui peut déterminer l'état des connexions, vous ne vous souciez plus vraiment de l'implémentation nécessaire pour connaître ces procédures.

Exemple :

#import <Foundation/Foundation.h>

@class Reachability;

@interface ConnectionManager : NSObject {
    Reachability *internetReachable;
    Reachability *hostReachable;
}

@property BOOL internetActive;
@property BOOL hostActive;

- (void) checkNetworkStatus:(NSNotification *)notice;

@end

Et le fichier .m :

#import "ConnectionManager.h"
#import "Reachability.h"

@implementation ConnectionManager
@synthesize internetActive, hostActive;

-(id)init {
    self = [super init];
    if(self) {

    }
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];

    internetReachable = [[Reachability reachabilityForInternetConnection] retain];
    [internetReachable startNotifier];

    hostReachable = [[Reachability reachabilityWithHostName:@"www.apple.com"] retain];
    [hostReachable startNotifier];

    return self;
}

- (void) checkNetworkStatus:(NSNotification *)notice {
    NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
    switch (internetStatus)

    {
        case NotReachable:
        {
            NSLog(@"The internet is down.");
            self.internetActive = NO;

            break;

        }
        case ReachableViaWiFi:
        {
            NSLog(@"The internet is working via WIFI.");
            self.internetActive = YES;

            break;

        }
        case ReachableViaWWAN:
        {
            NSLog(@"The internet is working via WWAN.");
            self.internetActive = YES;

            break;

        }
    }

    NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
    switch (hostStatus)

    {
        case NotReachable:
        {
            NSLog(@"A gateway to the host server is down.");
            self.hostActive = NO;

            break;

        }
        case ReachableViaWiFi:
        {
            NSLog(@"A gateway to the host server is working via WIFI.");
            self.hostActive = YES;

            break;

        }
        case ReachableViaWWAN:
        {
            NSLog(@"A gateway to the host server is working via WWAN.");
            self.hostActive = YES;

            break;

        }
    }

}

// If lower than SDK 5 : Otherwise, remove the observer as pleased.

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
}

@end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X