El mejor enfoque para verificar la connection a Internet en iOS

He estado buscando en Internet para encontrar la mejor manera de verificar la connection a Internet en iOS que funciona tanto en el entorno de networking IPv4 como IPv6. Descubrí que hay muchas respuestas posibles pero muy confundido sobre cuál aplicar. Lo que tengo que hacer es lo siguiente:

// Check for internet connection if (internetConnectionIsAvailable) { // make rest calls }else // show cached data } 

Encontré las siguientes opciones sugeridas en internet.

OPCIÓN 1: utilice la class de scope de manzana

Con Reachability puedo verificar la conectividad a Internet como sigue, que es corta y directa, y no tiene que esperar ninguna respuesta.

  - (BOOL)connected { Reachability *reachability = [Reachability reachabilityForInternetConnection]; NetworkStatus networkStatus = [reachability currentReachabilityStatus]; return !(networkStatus == NotReachable); } - (void)viewDidLoad { [super viewDidLoad]; if (![self connected]){ // Not connected }else{ // Connected } } 

Pero aquí la verificación de Internet se realiza en el pre vuelo, lo que está en contra de la sugerencia de ingeniero de Apple, como se ve en el video de WWDC . Además, si marca ReadMe.md, se ha mencionado que Reachability es totalmente compatible con IPv6. Pero si el método reachabilityForInternetConnection está marcado en Reachability.m, han utilizado sockaddr_in, sockaddr_in6 no se ha utilizado y se recomienda para la networking IPv6. Entonces no sé si funcionará en la networking IPv6.

OPCIÓN 2: usa Alamofire para conectar

  • Solo intente conectarse como en una de las respuestas stackoverflow . El código también se muestra a continuación:

     Alamofire.request(.GET,"http://superrandomdomainnamethatisnotused.com/superrandompath").responseString { (request, response, stringData, error) in if let networkError = error { if (networkError.code == -1009) { println("No Internet \(error)") } } } 

Pero no es mucho time para tratar de conectarse a un host, esperar la respuesta y luego saber si está en línea o sin connection.

OPCIÓN 3: Usa la versión de Alcance de Tony Million. Pero el autor ha advertido sobre la aplicación rechazada mientras usa esto. Puedo usar esto como el código que se muestra a continuación:

 // 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(@"There in internet connection"); }); }; // 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]; } 

Pero en esta opción, mi pregunta es: ¿es este enfoque correcto para probar Internet conectando http://google.com ? ¿Esto garantiza 100% de resultados? ¿Qué pasa si Google está inactivo? Si la aplicación se usa en el país donde google.com no está permitido, ¿cuál es el resultado?

Entonces, he tenido un gran dilema qué opción elegir, si estas opciones son las adecuadas o si hay una mejor manera de verificar Internet, lo que garantiza resultados al 100% y funciona tanto en la networking IPv4 como en la IPv6. ¿Alguien puede sugerirme qué opción es mejor o debo search otro enfoque? ¿Cuál es la mejor manera de lograrlo?

Su respuesta será muy apreciada.

Para Swift 3, Xcode 8 ……

 func isInternetAvailable() -> Bool { var zeroAddress = sockaddr_in() zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size) zeroAddress.sin_family = sa_family_t(AF_INET) guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, { $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { SCNetworkReachabilityCreateWithAddress(nil, $0) } }) else { return false } var flags: SCNetworkReachabilityFlags = [] if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) { return false } let isReachable = flags.contains(.reachable) let needsConnection = flags.contains(.connectionRequinetworking) return (isReachable && !needsConnection) } 

Creo que encontrará útil este enlace: Comprobación de la connection de networking que falla en las networkinges IPv6 en Swift

 import SystemConfiguration class Reachability { class func isConnectedToNetwork() -> Bool { var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress)) zeroAddress.sin_family = sa_family_t(AF_INET) let defaultRouteReachability = withUnsafePointer(&zeroAddress) { SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, UnsafePointer($0)) } var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0) if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false { return false } let isReachable = flags == .Reachable let needsConnection = flags == .ConnectionRequinetworking return isReachable && !needsConnection } } 

// caso de uso

 if Reachability.isConnectedToNetwork() { //do something } 

Aquí hay algunos otros enlaces para la investigación:

https://developer.apple.com/reference/systemconfiguration/1514904-scnetworkreachabilitycreatewithn

https://developer.apple.com/library/prerelease/content/documentation/Networking/Conceptual/SystemConfigFrameworks/SC_Intro/SC_Intro.html#//apple_ref/doc/uid/TP40001065

  1. Descargue la carpeta .zip de Github

  2. Descomprima la carpeta adjunta y arrastre y suelte los files en su proyecto.

  3. Cree un file bridge.h e importe con #import "Reachability.h" .

  4. Antes de invocar la API, puede verificar la connection a Internet con el siguiente código:

     if kNetworkController.checkNetworkStatus() { // call your api } 

Eso es.