Come verificare la presenza di una connessione Internet attiva su iOS o macOS?


1326

Vorrei verificare se ho una connessione Internet su iOS usando le librerie Cocoa Touch o su macOS usando le librerie Cocoa .

Ho trovato un modo per farlo usando un NSURL. Il modo in cui l'ho fatto sembra un po 'inaffidabile (perché anche un giorno Google potrebbe essere inattivo e fare affidamento su una terza parte sembra male), e mentre potrei controllare per vedere una risposta da altri siti Web se Google non ha risposto, sembra dispendioso e un sovraccarico inutile sulla mia domanda.

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

È ciò che ho fatto di male (per non parlare del fatto che stringWithContentsOfURLè deprecato in iOS 3.0 e macOS 10.4) e, in tal caso, qual è il modo migliore per farlo?


11
Piuttosto return (BOOL)URLString;, o meglio, return !!URLStringoppurereturn URLString != nil

3
Non so quale sia il tuo caso d'uso, ma se puoi è preferibile provare la richiesta e gestire eventuali errori come la mancanza di connessione. Se non puoi farlo, allora ci sono molti buoni consigli qui in questo caso.
SK9

2
La tua soluzione è intelligente e la preferisco. Puoi anche usare NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://twitter.com/getibox"] encoding:NSUTF8StringEncoding error:nil];Per sbarazzarti del fastidioso avvertimento.
Abdelrahman Eid,

4
prova a utilizzare la classe di Raggiungibilità dal link seguente, funzionerà per te github.com/tonymillion/Reachability
Dhaval H. Nena

4
Per quelli recentemente trovare questa risposta: stackoverflow.com/a/8813279
afollestad

Risposte:


1285

Importante : questo controllo deve essere sempre eseguito in modo asincrono. La maggior parte delle risposte di seguito sono sincrone, quindi fai attenzione, altrimenti congelerai la tua app.


veloce

1) Installa tramite CocoaPods o Carthage: https://github.com/ashleymills/Reachability.swift

2) Test di raggiungibilità tramite chiusure

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

Objective-C

1) Aggiungi un SystemConfigurationframework al progetto ma non preoccuparti di includerlo ovunque

2) Aggiungi la versione di Tony Million Reachability.he Reachability.mal progetto (disponibile qui: https://github.com/tonymillion/Reachability )

3) Aggiorna la sezione dell'interfaccia

#import "Reachability.h"

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

4) Quindi implementare questo metodo nel file .m del controller della vista che è possibile chiamare

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

Nota importante: la Reachabilityclasse è una delle classi più utilizzate nei progetti, pertanto è possibile che si verifichino conflitti di denominazione con altri progetti. In questo caso, dovrai rinominare una delle coppie di Reachability.he Reachability.mfile in qualcos'altro per risolvere il problema.

Nota: il dominio che usi non ha importanza. Sta solo testando un gateway per qualsiasi dominio.


4
@gonzobrains: il dominio che usi non ha importanza. Sta solo testando un gateway per qualsiasi dominio.
rapito il

3
@KaanDedeoglu È solo un esempio, usa qualunque dominio tu voglia. Controlla semplicemente un gateway per Internet, non che il dominio sia effettivamente disponibile.
ucciso

1
Oh, a proposito è necessario aggiungere anche SystemConfiguration.frameworkal progetto (per il metodo 1).
saggio

2
Usa www.appleiphonecell.com invece di google.com: questo URL è stato creato da Apple proprio per questo motivo.
Smikey,

1
L'uso di www.appleiphonecell.com è ora (2018) una cattiva scelta. Ora reindirizza ad Apple.com che è un file html> 40kB. Torna a google.com: sono solo 11 KB. BTW google.com/m ha le stesse dimensioni ma è segnalato per essere più lento di 120 msec.
BlueskyMed,

311

Mi piace mantenere le cose semplici. Il modo in cui lo faccio è:

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

Quindi, lo uso ogni volta che voglio vedere se ho una connessione:

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

Questo metodo non attende gli stati di rete modificati per eseguire operazioni. Verifica solo lo stato quando lo chiedi.


Ciao @msec, puoi provare la soluzione Andrew Zimmer in questa pagina, funziona bene con adsl disconnesso (e wifi connesso)
Williew

1
Per quelli che hanno appena copiato e incollato come ho fatto con il codice sopra. Aggiungi anche SystemConfiguration.framework manualmente o otterrai un errore di collegamento.
Iftikhar Ali Ansari,

Vieni sempre come raggiungibile se mi connetto con WiFi. WiFi non significa che abbia una connessione Internet. Voglio verificare la connessione a Internet anche se ha la connettività WiFi. Potete per favore aiutarmi?
Wesley,

@wesley Come l'hai risolto?
Keselme,

146

Usando il codice di raggiungibilità di Apple, ho creato una funzione che lo controllerà correttamente senza che tu debba includere alcuna classe.

Includi SystemConfiguration.framework nel tuo progetto.

Effettua alcune importazioni:

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

Ora chiama questa funzione:

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

Ed è iOS 5 testato per te.


@JezenThomas Questo non esegue il controllo di Internet in modo asincrono, motivo per cui è "molto più sottile" ... Dovresti sempre farlo in modo asincrono iscrivendoti alle notifiche in modo da non appendere l'app in questo processo.
ucciso

Grazie, questo lavoro anche se stai usando wifi adsl e adsl non è connesso, è esattamente quello di cui ho bisogno.
Williew,

5
Questo perde memoria - la struttura della "leggibilità" (oggetto, cosa) deve essere liberata con CFRelease ().
Russell Mull,

@RussellMull ... hai idea di come riparare la perdita?
i_raqz,

Strano che questa risposta preceda la mia (su una domanda contrassegnata come duplicata) di 2 anni, è esattamente la stessa della mia, ma non l'ho mai vista fino ad oggi.
ArtOfWarfare il

122

Questa era la risposta corretta, ma ora è obsoleta in quanto è necessario sottoscrivere le notifiche per la raggiungibilità. Questo metodo controlla in modo sincrono:


Puoi utilizzare la classe di raggiungibilità di Apple. Ti permetterà anche di verificare se il Wi-Fi è abilitato:

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 di raggiungibilità non viene fornita con l'SDK, ma piuttosto una parte di questa applicazione di esempio Apple . Scaricalo e copia Reachability.h / m nel tuo progetto. Inoltre, devi aggiungere il framework SystemConfiguration al tuo progetto.


6
Vedi il mio commento sopra sul non usare Reachability in quel modo. Usalo in modalità asincrona e iscriviti alle notifiche che invia - non farlo.
Kendall Helmstetter Gelner,

Questo codice è un buon punto di partenza per le cose che è necessario impostare prima di poter utilizzare i metodi delegati per la classe di raggiungibilità.
Brock Woolf,

82

Ecco una risposta molto semplice:

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 dovrebbe puntare a un sito Web estremamente piccolo. Uso il sito Web mobile di Google qui, ma se avessi un server Web affidabile, caricarei un piccolo file con un solo carattere per la massima velocità.

Se verificare se il dispositivo è in qualche modo connesso a Internet è tutto ciò che vuoi fare, ti consiglio vivamente di utilizzare questa semplice soluzione. Se hai bisogno di sapere come è connesso l'utente, utilizzare Raggiungibilità è la strada da percorrere.

Attenzione: questo bloccherà brevemente il tuo thread mentre carica il sito web. Nel mio caso, questo non è stato un problema, ma dovresti considerare questo (crediti a Brad per averlo sottolineato).


10
Questa idea mi piace molto, ma direi per l'affidabilità del 99,999% pur mantenendo una dimensione di risposta ridotta, vai su www.google.com/m che è la visualizzazione mobile per google.
rwyland,

1
Fantastica soluzione @Erik. Quello che ti consiglio anche è di utilizzare www.google.com, anziché www.google.com/m, come ha detto la Ruanda. È strano, ma dal mio test la versione mobile impiega sempre circa 120 ms in più rispetto a www.google.com
Sebyddd

4
I documenti Apple consigliano di non farlo poiché può bloccare il thread su una rete lenta, può causare la chiusura dell'app in iOS
Brad Thomas

Grazie per il feedback positivo, accetta che www.google.com/m sia la soluzione migliore per affidabilità!
Erik

3
LOL, sono sicuro che Google apprezzi che hai suggerito alle persone di usarle come risorsa di controllo di Internet.
mxcl,

73

Ecco come lo faccio nelle mie app: Mentre un codice di risposta di stato 200 non garantisce nulla, è abbastanza stabile per me. Questo non richiede tanto caricamento quanto le risposte NSData pubblicate qui, poiché la mia controlla solo la risposta HEAD.

codice SWIFT

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

Codice Obiettivo-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
         }
    }];
}

3
Sembra che questo sia il modo più veloce
Pavel

3
Attenzione: nella mia esperienza, questa soluzione non funziona sempre. In molti casi la risposta restituita è 403, dopo aver preso il suo dolce momento. Questa soluzione sembrava perfetta, ma non garantisce risultati al 100%.
Mustafa,

10
A partire da giugno 2014, questo fallirà nella Cina continentale, a causa del fatto che il governo cinese sta bloccando completamente google.com. (google.cn funziona, però, ma nella Cina continentale, niente baidu.com, niente internet) Probabilmente è meglio eseguire il ping con qualsiasi server con cui devi comunicare.
prewett,

4
Usa invece www.appleiphonecell.com - apple ha creato questo URL proprio per questo motivo.
Smikey,

1
Ho usato appleiphonecell in quanto è di proprietà di Apple, può essere utilizzato anche in Cina ed è un sito Web molto veloce. Questo, insieme alla tua risposta, mi ha fornito la soluzione più vicina e più veloce. Grazie
Septronic,

57

Apple fornisce un codice di esempio per verificare la disponibilità di diversi tipi di rete. In alternativa c'è un esempio nel ricettario degli sviluppatori di iPhone.

Nota: vedi il commento di @ KHG su questa risposta sull'uso del codice di raggiungibilità di Apple.


Grazie. Ho scoperto che la documentazione Xcode in 3.0 contiene anche il codice sorgente, trovato cercando "raggiungibilità" nella documentazione.
Brock Woolf,

7
Si noti che la nuova revisione (09-08-09) del codice di esempio di raggiungibilità di Apple è asincrona.
Daniel Hepper,

46

È possibile utilizzare Reachabilityda  ( disponibile qui ).

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

@Supertecnoboff No, è asincrono.
Aleksander Azizi,

39

Apple fornisce un'app di esempio che fa esattamente questo:

raggiungibilità


7
Si noti che l'esempio di raggiungibilità rileva solo quali interfacce sono attive, ma non quali hanno una connessione valida a Internet. Le applicazioni dovrebbero gestire con grazia i guasti anche quando Reachability riporta che tutto è pronto per partire.
rpetrich,

Fortunatamente la situazione è molto migliore in 3.0, poiché il sistema presenterà una pagina di accesso per gli utenti dietro un WiFi bloccato in cui è necessario effettuare l'accesso per utilizzare ... è necessario verificare manualmente il reindirizzamento (e lo si fa ancora se si sviluppano app 2.2.1)
Kendall Helmstetter Gelner,

Non direi che l'app Raggiungibilità fa esattamente ciò che viene richiesto. Tuttavia è un buon punto di partenza per aggiungere il tipo di funzionalità richiesta,
Johan Karlsson

Link interrotto !, apprezzeremmo se questo può essere controllato / riparato, molte grazie
Heider Sati,

33

È stata aggiornata solo la classe di raggiungibilità. Ora puoi usare:

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

1
A meno che qualcosa non sia cambiato da quando è stato rilasciato 4.0, quel codice non è asincrono e si è certi di vederlo apparire in Crash Reports - mi è successo prima.
bpapa,

1
Sono d'accordo con bpapa. Non è una buona idea usare il codice sincrono. Grazie per le informazioni però
Brock Woolf,



22

Se stai usando AFNetworking , puoi utilizzare la propria implementazione per lo stato di raggiungibilità di Internet.

Il modo migliore per usare AFNetworkingè sottoclasse ilAFHTTPClient classe e utilizzare questa classe per eseguire le connessioni di rete.

Uno dei vantaggi dell'utilizzo di questo approccio è che è possibile utilizzare blocksper impostare il comportamento desiderato quando lo stato di raggiungibilità cambia. Supponendo di aver creato una sottoclasse singleton di AFHTTPClient(come detto nelle "Note sulla sottoclasse" nei documenti di AFNetworking ) BKHTTPClient, farei qualcosa del tipo:

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

Si potrebbe anche verificare la presenza di connessioni Wi-Fi o WLAN specificamente utilizzando l' AFNetworkReachabilityStatusReachableViaWWANe AFNetworkReachabilityStatusReachableViaWiFienumerazioni ( di più qui ).


18

Ho usato il codice in questa discussione e sembra funzionare bene (leggi il tutto thread!).

Non l'ho testato esaurientemente con ogni tipo immaginabile di connessione (come il Wi-Fi ad hoc).


questo codice non è del tutto buono perché controlla solo se hai una connessione wifi con un router, non se il web è raggiungibile. Puoi avere il wifi funzionante e continuare abilitare per raggiungere il web.
DuckDucking,

15

Molto semplice .... Prova questi passaggi:

Passaggio 1: aggiungere il SystemConfigurationframework al progetto.


Passaggio 2: importare il seguente codice nel headerfile.

#import <SystemConfiguration/SystemConfiguration.h>

Passaggio 3: utilizzare il seguente metodo

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

  • Tipo 2:

    Importa intestazione :#import "Reachability.h"

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

Passaggio 4: come usare:

- (void)CheckInternet
{
    BOOL network = [self currentNetworkStatus];
    if (network)
    {
        NSLog(@"Network Available");
    }
    else
    {
        NSLog(@"No Network Available");
    }
}

Il tipo 1 è asincrono?
Supertecnoboff,

Voglio le correzioni di tipo 2 dalla tua risposta. Ho aggiunto le classi di raggiungibilità e ho provato a verificare la verifica della connessione utilizzando sopra la risposta. arriva sempre raggiungibile anche se mi connetto con WiFi ma non ha la connessione a Internet. WiFi non significa che abbia una connessione Internet. Voglio verificare la connessione a Internet anche se ha la connettività WiFi. Potete per favore aiutarmi?
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;
}
}

7
Anche se il dispositivo è connesso a una rete WiFi o ad un altro tipo di rete, la connessione Internet potrebbe non essere ancora disponibile. Test semplice: connettiti al tuo wifi di casa e quindi scollega il modem via cavo. Ancora connesso al wifi, ma zero internet.
ucciso il

11
- (void)viewWillAppear:(BOOL)animated
{
    NSString *URL = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];

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

Oppure usa la classe di Raggiungibilità .

Esistono due modi per verificare la disponibilità di Internet utilizzando l'SDK di iPhone:

1. Controlla che la pagina di Google sia aperta o meno.

2. Classe di raggiungibilità

Per ulteriori informazioni, fare riferimento a Raggiungibilità (sviluppatore Apple).


1
Esistono due modi per verificare la disponibilità di Internet in iPhone SDK 1) Verificare che la pagina di Google sia aperta o meno.
IOS Rocks,

1
-1: questo è un metodo sincrono che bloccherà il thread principale (quello su cui viene modificata l'interfaccia utente dell'app) mentre tenta di connettersi a google.com. Se l'utente utilizza una connessione dati molto lenta, il telefono agirà come se il processo non rispondesse.
ucciso il


10

Primo : AggiungiCFNetwork.framework nel framework

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

8

Per prima cosa scarica la classe di raggiungibilità e inserisci i file reachability.h e reachabilty.m nel tuo Xcode .

Il modo migliore è creare una classe Funzioni comune (NSObject) in modo da poterla utilizzare in qualsiasi classe. Questi sono due metodi per un controllo di raggiungibilità della connessione di rete:

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

Ora puoi controllare la connessione di rete in qualsiasi classe chiamando questo metodo di classe.


8

Esiste anche un altro metodo per verificare la connessione a Internet utilizzando l'SDK di iPhone.

Prova a implementare il seguente codice per la connessione di rete.

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


8
  1. Scarica il file di raggiungibilità, https://gist.github.com/darkseed/1182373

  2. E aggiungi CFNetwork.frameworke 'SystemConfiguration.framework' nel framework

  3. Fai #import "Reachability.h"


Primo : aggiungiCFNetwork.framework nel framework

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

8

Swift 3 / Swift 4

Devi prima importare

import SystemConfiguration

È possibile verificare la connessione Internet con il seguente metodo

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)

}

7

La classe di raggiungibilità è OK per scoprire se la connessione Internet è disponibile per un dispositivo o no ...

Ma in caso di accesso a una risorsa intranet :

Il ping del server Intranet con la classe di raggiungibilità restituisce sempre true.

Quindi una soluzione rapida in questo scenario sarebbe quella di creare un metodo web chiamato pingmeinsieme ad altri metodi web sul servizio. Ilpingme dovrebbe restituire qualcosa.

Quindi ho scritto il seguente metodo su funzioni comuni

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

Il metodo di cui sopra è stato molto utile per me, quindi ogni volta che provo a inviare alcuni dati al server controllo sempre la raggiungibilità della mia risorsa intranet usando questo URLRequest a basso timeout.


7

Farlo da soli è estremamente semplice. Il seguente metodo funzionerà. Assicurati solo di non consentire a un protocollo hostname come HTTP, HTTPS, ecc. Di essere passato con il nome.

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

È veloce, semplice e indolore.



7

Penso che questa sia la migliore risposta.

"Sì" significa connesso. "No" significa disconnesso.

#import "Reachability.h"

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

    if (internetStats == NotReachable)
    {
        return NO;
    }
    else
    {
        return YES;
    }
}

6

Importa la Reachable.hclasse nel tuo ViewControllere usa il seguente codice per verificare la connettività :

     #define hasInternetConnection [[Reachability reachabilityForInternetConnection] isReachable]
     if (hasInternetConnection){
           // To-do block
     }

La tua risposta è esattamente quello che sto cercando. Vostro signore merita un voto in più xD
Nikel Arteta,

Non funziona se si è connessi a un WiFi senza Internet.
Keselme, il

6
  • Passaggio 1: aggiungi la classe di raggiungibilità nel tuo progetto.
  • Passaggio 2: importare la classe di raggiungibilità
  • Passaggio 3: creare la funzione seguente

    - (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;
            }
        }
    }
  • Passaggio 4: chiamare la funzione come di seguito:

    if (![self checkNetConnection]) {
        [GlobalFunctions showAlert:@""
                         message:@"Please connect to the Internet!"
                         canBtntitle:nil
                         otherBtnTitle:@"Ok"];
        return;
    }
    else
    {
        Log.v("internet is connected","ok");
    }

I documenti di Apple affermano questa Nota: la raggiungibilità non può dire all'applicazione se è possibile connettersi a un determinato host, solo che è disponibile un'interfaccia che potrebbe consentire una connessione e se tale interfaccia è WWAN.
noobsmcgoobs,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.