¿Cómo verificar una conexión a Internet activa en iOS o macOS?

1326

Me gustaría verificar si tengo una conexión a Internet en iOS usando las bibliotecas Cocoa Touch o en macOS usando las bibliotecas Cocoa .

Se me ocurrió una manera de hacer esto usando un NSURL. La forma en que lo hice parece un poco poco confiable (porque incluso Google podría algún día estar caído y depender de un tercero parece malo), y si bien podría verificar si hay alguna respuesta de algunos otros sitios web si Google no respondió, parece un desperdicio y una sobrecarga innecesaria en mi aplicación.

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

Es lo que he hecho mal (sin mencionar que stringWithContentsOfURLestá en desuso en iOS 3.0 y macOS 10.4) y, de ser así, ¿cuál es una mejor manera de lograrlo?

Brock Woolf
fuente
11
Más bien return (BOOL)URLString;, o incluso mejor, return !!URLStringoreturn URLString != nil
3
No sé cuál es su caso de uso, pero si puede, es preferible probar la solicitud y manejar cualquier error como la falta de conexión que surja. Si no puede hacer esto, entonces hay muchos buenos consejos aquí en este caso.
SK9 01 de
2
Su solución es inteligente, y la prefiero. También puedes usar NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://twitter.com/getibox"] encoding:NSUTF8StringEncoding error:nil];Para deshacerte de la molesta advertencia.
Abdelrahman Eid
44
intente usar la clase de accesibilidad desde el siguiente enlace, funcionará para usted github.com/tonymillion/Reachability
Dhaval H. Nena
44
Para aquellos que recientemente encontraron esta respuesta: stackoverflow.com/a/8813279
afollestad

Respuestas:

1285

Importante : esta verificación siempre debe realizarse de forma asíncrona. La mayoría de las respuestas a continuación son sincrónicas, así que tenga cuidado, de lo contrario, congelará su aplicación.


Rápido

1) Instalar a través de CocoaPods o Carthage: https://github.com/ashleymills/Reachability.swift

2) Prueba de accesibilidad a través de cierres

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

C objetivo

1) Agregue SystemConfigurationmarco al proyecto pero no se preocupe por incluirlo en ningún lado

2) Agregue la versión de Tony Million Reachability.hy Reachability.mal proyecto (que se encuentra aquí: https://github.com/tonymillion/Reachability )

3) Actualiza la sección de interfaz

#import "Reachability.h"

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

4) Luego implemente este método en el archivo .m de su controlador de vista al que puede llamar

// 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 Reachabilityclase es una de las clases más utilizadas en los proyectos, por lo que puede tener conflictos de nombres con otros proyectos. Si esto sucede, deberá cambiar el nombre de uno de los pares de Reachability.hy Reachability.marchivos a otra cosa para resolver el problema.

Nota: El dominio que usa no importa. Solo está probando una puerta de enlace a cualquier dominio.

Me han robado
fuente
44
@gonzobrains: el dominio que usas no importa. Solo está probando una puerta de enlace a cualquier dominio.
Fui robado el
3
@KaanDedeoglu Es solo un ejemplo, use el dominio que desee. Simplemente busca una puerta de enlace a Internet, no que el dominio esté realmente disponible.
Fui robado
1
Ah, por cierto, también necesita agregar SystemConfiguration.frameworkal proyecto (para el método 1).
wiseindy
2
Use www.appleiphonecell.com en lugar de google.com: esta url fue creada por apple precisamente por esta razón.
Smikey
1
El uso de www.appleiphonecell.com es ahora (2018) una mala elección. Ahora redirige a Apple.com, que es un archivo html> 40kB. Regreso a google.com: solo tiene 11kB. Por cierto, google.com/m tiene el mismo tamaño, pero se informa que es más lento en 120 ms.
BlueskyMed
311

Me gusta mantener las cosas simples. La forma en que hago esto es:

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

Luego, uso esto cada vez que quiero ver si tengo una conexión:

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

Este método no espera cambios en los estados de la red para hacer cosas. Simplemente prueba el estado cuando se lo pides.

cannyboy
fuente
Hola @msec, puedes probar la solución de Andrew Zimmer en esta página, funciona bien con adsl desconectado (y wifi conectado)
Williew
1
Para aquellos que simplemente copian y pegan como lo hice con el código anterior. Agregue también SystemConfiguration.framework manualmente o obtendrá un error de enlace.
Iftikhar Ali Ansari
Siempre llega como accesible si me conecto con WiFi. WiFi no significa que tenga conexión a internet. Quiero verificar la conexión a Internet, incluso si tiene conectividad WiFi. ¿Puedes ayudarme por favor?
wesley
@wesley ¿Cómo lo resolviste?
Keselme
146

Usando el código de accesibilidad de Apple, creé una función que verificará esto correctamente sin que tenga que incluir ninguna clase.

Incluya el SystemConfiguration.framework en su proyecto.

Haz algunas importaciones:

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

Ahora solo llame a esta función:

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

Y es iOS 5 probado para ti.

Andrew Zimmer
fuente
@JezenThomas Esto no realiza la comprobación de Internet de forma asincrónica, por lo que es "mucho más delgado" ... Siempre debe hacerlo asincrónicamente suscribiéndose a notificaciones para que no cuelgue la aplicación en este proceso.
Fui robado
Gracias, este trabajo, incluso si está utilizando wifi adsl y adsl no está conectado, es exactamente lo que necesito.
Williew
55
Esto pierde memoria: la estructura de 'legibilidad' (objeto, cosa) debe liberarse con CFRelease ().
Russell Mull
@RussellMull ... ¿alguna idea de cómo solucionar la fuga?
i_raqz
Es extraño que esta respuesta sea anterior a la mía (en una pregunta marcada como duplicada) por 2 años, es exactamente la misma que la mía, pero nunca la vi hasta hoy.
ArtOfWarfare
122

Esta solía ser la respuesta correcta, pero ahora está desactualizada ya que en su lugar debes suscribirte a las notificaciones de accesibilidad. Este método verifica sincrónicamente:


Puedes usar la clase de accesibilidad de Apple. También le permitirá verificar si el Wi-Fi está habilitado:

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 clase de accesibilidad no se incluye con el SDK, sino que forma parte de esta aplicación de muestra de Apple . Simplemente descárguelo y copie Reachability.h / m a su proyecto. Además, debe agregar el marco de SystemConfiguration a su proyecto.

Daniel Rinser
fuente
66
Vea mi comentario anterior sobre no usar Alcance de esa manera. Úselo en modo asíncrono y suscríbase a las notificaciones que envía, no lo haga.
Kendall Helmstetter Gelner el
Este código es un buen punto de partida para las cosas que necesita establecer antes de poder usar los métodos delegados para la clase de accesibilidad.
Brock Woolf el
82

Aquí hay una respuesta muy 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");

La URL debe apuntar a un sitio web extremadamente pequeño. Uso el sitio web móvil de Google aquí, pero si tuviera un servidor web confiable, subiría un pequeño archivo con solo un carácter. para obtener la máxima velocidad.

Si verifica si el dispositivo es de alguna manera lo que desea hacer conectado a Internet de , definitivamente recomendaría usar esta solución simple. Si necesita saber cómo está conectado el usuario, utilizar la accesibilidad es el camino a seguir.

Cuidado: esto bloqueará brevemente tu hilo mientras carga el sitio web. En mi caso, esto no fue un problema, pero deberías considerarlo (agradece a Brad por señalar esto).

Erik
fuente
10
Realmente me gusta esta idea, pero diría que para el 99.999% de confiabilidad mientras se mantiene un tamaño de respuesta pequeño, vaya a www.google.com/m, que es la vista móvil para google.
rwyland
1
Impresionante solución @Erik. Lo que también le recomiendo es que use www.google.com, en lugar de www.google.com/m, como dijo rwyland. Es extraño, pero según mi prueba, la versión móvil siempre tarda unos 120 ms más que la www.google.com
Sebyddd
44
Los documentos de Apple recomiendan no hacer esto, ya que puede bloquear el hilo en una red lenta, puede hacer que la aplicación se cierre en iOS
Brad Thomas
Gracias por los comentarios positivos, ¡acepta que www.google.com/m es la mejor solución debido a la confiabilidad!
Erik
3
LOL, estoy seguro de que Google aprecia que sugieras que las personas los usen como un recurso de verificación de Internet.
mxcl
73

Así es como lo hago en mis aplicaciones: si bien un código de respuesta de estado 200 no garantiza nada, es lo suficientemente estable para mí. Esto no requiere tanta carga como las respuestas de NSData publicadas aquí, ya que la mía solo verifica la respuesta HEAD.

código 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
        }
    })
}

Código 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
fuente
3
Parece que esta es la forma más rápida
Pavel
3
Precaución: en mi experiencia, esta solución no funciona todo el tiempo. En muchos casos, la respuesta devuelta es 403, después de tomar su dulce momento. Esta solución parecía perfecta, pero no garantiza resultados 100%.
Mustafa
10
A partir de junio de 2014, esto fallará en China continental, debido a que el gobierno chino ahora bloquea completamente google.com. (google.cn funciona, sin embargo, pero en China continental, sin baidu.com, sin internet) Probablemente sea mejor hacer ping a cualquier servidor con el que necesite comunicarse.
prewett
44
Utilice www.appleiphonecell.com en su lugar: Apple creó esta url precisamente por este motivo.
Smikey
1
Solía appleiphonecell ya que es la propia Apple, se puede utilizar también en China, y es un sitio web muy rápido. Esto, junto con su respuesta, me proporcionó la solución más cercana y rápida. Gracias
Septronic
57

Apple proporciona un código de muestra para verificar los diferentes tipos de disponibilidad de red. Alternativamente, hay un ejemplo en el libro de cocina para desarrolladores de iPhone.

Nota: Consulte el comentario de @ KHG sobre esta respuesta con respecto al uso del código de accesibilidad de Apple.

teabot
fuente
Gracias. Descubrí que la documentación de Xcode en 3.0 también contiene el código fuente, que se encuentra al buscar "accesibilidad" en la documentación.
Brock Woolf el
77
Tenga en cuenta que la nueva revisión (09-08-09) del código de muestra de Accesibilidad de Apple es asíncrona.
Daniel Hepper el
46

Podrías usar Reachabilitypor  ( disponible aquí ).

#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
fuente
@Supertecnoboff No, es asíncrono.
Aleksander Azizi
39

Apple proporciona una aplicación de muestra que hace exactamente esto:

Alcance

NANNAV
fuente
77
Debe tener en cuenta que la muestra de Accesibilidad solo detecta qué interfaces están activas, pero no cuáles tienen una conexión válida a Internet. Las aplicaciones deben manejar correctamente las fallas incluso cuando Alcance informa que todo está listo para funcionar.
rpetrich el
Afortunadamente, la situación es mucho mejor en 3.0, ya que el sistema presentará una página de inicio de sesión para los usuarios detrás de un WiFi bloqueado en el que debe iniciar sesión para usar ... solía tener que verificar la redirección manualmente (y aún lo hace si desarrolla aplicaciones 2.2.1)
Kendall Helmstetter Gelner el
No diría que la aplicación de accesibilidad hace exactamente lo que se le pide. Sin embargo, es un buen punto de partida para agregar el tipo de funcionalidad que se solicita,
Johan Karlsson el
Enlace roto !, agradecería si esto se puede verificar / arreglar, muchas gracias
Heider Sati
33

Solo se ha actualizado la clase de accesibilidad. Ahora puedes usar:

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
fuente
1
A menos que algo haya cambiado desde que se lanzó 4.0, ese código no es asíncrono y se garantiza que lo verá aparecer en Informes de bloqueo, me sucedió antes.
bpapa
1
Estoy de acuerdo con bpapa. No es una buena idea usar código sincrónico. Gracias por la información sin embargo
Brock Woolf
25

Aquí hay una bonita modernización de accesibilidad mediante ARC y GCD:

Alcance

JK Laiho
fuente
22

Si estas usando AFNetworking , puede usar su propia implementación para el estado de accesibilidad a Internet.

La mejor manera de usar AFNetworkinges subclasificar elAFHTTPClient clase y usar esta clase para hacer sus conexiones de red.

Una de las ventajas de usar este enfoque es que puede usar blockspara establecer el comportamiento deseado cuando cambia el estado de accesibilidad. Suponiendo que he creado una subclase singleton de AFHTTPClient(como se dice en las "Notas de subclasificación" en documentos de AFNetworking ) con nombre BKHTTPClient, haría algo como:

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

También puede verificar las conexiones Wi-Fi o WLAN específicamente usando las enumeraciones AFNetworkReachabilityStatusReachableViaWWANy AFNetworkReachabilityStatusReachableViaWiFi( más aquí ).

Bruno Koga
fuente
18

He usado el código en esta discusión , y parece funcionar bien (lea todo hilo!).

No lo he probado exhaustivamente con todos los tipos de conexión imaginables (como Wi-Fi ad hoc).

Felixyz
fuente
este código no es totalmente bueno porque solo verifica si tiene conexión wifi con un enrutador, no si se puede acceder a la web. Puede tener wifi funcionando y continuar habilitando para llegar a la web.
DuckDucking el
15

Muy simple ... Pruebe estos pasos:

Paso 1: agrega el SystemConfigurationmarco a tu proyecto.


Paso 2: importe el siguiente código en su headerarchivo.

#import <SystemConfiguration/SystemConfiguration.h>

Paso 3: usa el siguiente método

  • 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:

    Importar encabezado :#import "Reachability.h"

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

Paso 4: Cómo usar:

- (void)CheckInternet
{
    BOOL network = [self currentNetworkStatus];
    if (network)
    {
        NSLog(@"Network Available");
    }
    else
    {
        NSLog(@"No Network Available");
    }
}
Rajesh Loganathan
fuente
¿El tipo 1 es asíncrono?
Supertecnoboff
Quiero las correcciones de tipo 2 de tu respuesta. Agregué las clases de accesibilidad e intenté verificar la verificación de la conexión usando tu respuesta. siempre es accesible incluso si me conecto con WiFi pero no tiene conexión a Internet. WiFi no significa que tenga conexión a internet. Quiero verificar la conexión a Internet, incluso si tiene conectividad WiFi. ¿Puedes ayudarme por favor?
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
fuente
77
Incluso si el dispositivo está conectado a Wifi u otro tipo de red, la conexión a Internet puede no estar disponible. Prueba simple: conéctese al wifi de su hogar y luego desconecte su cable módem. Todavía conectado a wifi, pero internet cero.
Fui robado el
11
- (void)viewWillAppear:(BOOL)animated
{
    NSString *URL = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];

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

O use la clase de accesibilidad .

Hay dos formas de verificar la disponibilidad de Internet utilizando el SDK de iPhone:

1. Verifique que la página de Google esté abierta o no.

2. Clase de accesibilidad

Para obtener más información, consulte Accesibilidad (Desarrollador de Apple).

IOS Rocks
fuente
1
Hay dos formas de verificar la disponibilidad de Internet en el SDK de iPhone 1) Verifique que la página de Google esté abierta o no.
IOS Rocks
1
-1: Este es un método sincrónico que bloqueará el hilo principal (en el que se cambia la interfaz de usuario de la aplicación) mientras intenta conectarse a google.com. Si su usuario tiene una conexión de datos muy lenta, el teléfono actuará como si el proceso no respondiera.
Fui robado el
10

Primero : Agregar CFNetwork.frameworken el marco

Código :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
fuente
8

Primero descargue la clase de accesibilidad y coloque el archivo reachability.h y reachabilty.m en su Xcode .

La mejor manera es crear una clase de Funciones común (NSObject) para que pueda usarla en cualquier clase. Estos son dos métodos para verificar la accesibilidad de la conexión de red:

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

Ahora puede verificar la conexión de red en cualquier clase llamando a este método de clase.

Latika Tiwari
fuente
8

También hay otro método para verificar la conexión a Internet utilizando el SDK de iPhone.

Intente implementar el siguiente código para la conexión de red.

#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
fuente
8
  1. Descargue el archivo de accesibilidad, https://gist.github.com/darkseed/1182373

  2. Y agregue CFNetwork.frameworky 'SystemConfiguration.framework' en el marco

  3. Importa # "Accesibilidad.h"


Primero : Agregar CFNetwork.frameworken el marco

Código :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
fuente
8

Swift 3 / Swift 4

Primero debes importar

import SystemConfiguration

Puede verificar la conexión a internet con el siguiente método

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
fuente
7

La clase de accesibilidad está bien para averiguar si la conexión a Internet está disponible para un dispositivo o no ...

Pero en caso de acceder a un recurso de intranet :

Hacer ping al servidor de intranet con la clase de accesibilidad siempre devuelve verdadero.

Entonces, una solución rápida en este escenario sería crear un método web llamado pingmejunto con otros métodos web en el servicio. El pingmedebería devolver algo.

Entonces escribí el siguiente método sobre funciones comunes

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

El método anterior fue muy útil para mí, por lo que cada vez que intento enviar algunos datos al servidor siempre verifico la accesibilidad de mi recurso de intranet utilizando este URLRequest de tiempo de espera bajo.

Durai Amuthan.H
fuente
7

Hacer esto usted mismo es extremadamente simple. El siguiente método funcionará. Solo asegúrese de no permitir que un protocolo de nombre de host como HTTP, HTTPS, etc. se pase con el nombre.

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

Es rápido, simple e indoloro.

Tony
fuente
7

Creo que esta es la mejor respuesta.

"Sí" significa conectado. "No" significa desconectado.

#import "Reachability.h"

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

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

Importe la Reachable.hclase en su ViewController, y use el siguiente código para verificar la conectividad :

     #define hasInternetConnection [[Reachability reachabilityForInternetConnection] isReachable]
     if (hasInternetConnection){
           // To-do block
     }
Himanshu Mahajan
fuente
Tu respuesta es exactamente lo que estoy buscando. Usted señor merece un voto xD
Nikel Arteta
No funciona si está conectado a un WiFi sin internet.
Keselme
6
  • Paso 1: agregue la clase de accesibilidad en su proyecto.
  • Paso 2: importe la clase de accesibilidad
  • Paso 3: crea la siguiente función

    - (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;
            }
        }
    }
  • Paso 4: llame a la función de la siguiente manera:

    if (![self checkNetConnection]) {
        [GlobalFunctions showAlert:@""
                         message:@"Please connect to the Internet!"
                         canBtntitle:nil
                         otherBtnTitle:@"Ok"];
        return;
    }
    else
    {
        Log.v("internet is connected","ok");
    }
Anny
fuente
Los documentos de Apple indican esta Nota: La accesibilidad no puede decirle a su aplicación si puede conectarse a un host en particular, solo que hay una interfaz disponible que podría permitir una conexión y si esa interfaz es la WWAN.
noobsmcgoobs