2016-08-02 8 views
8

Ich habe über das Internet gesucht, um die beste Möglichkeit zur Überprüfung der Internetverbindung in iOS zu finden, die sowohl in IPv4 als auch in IPv6-Netzwerkumgebung funktioniert. Ich fand, dass es viele mögliche Antworten gibt, aber sehr verwirrt, auf welche man sich bezieht. Was ich tun muss, ist folgendes:Beste Methode zum Überprüfen der Internetverbindung in iOS

// Check for internet connection 

if (internetConnectionIsAvailable) { 
    // make rest calls 
}else 
    // show cached data 
} 

Ich fand die folgenden Optionen, die im Internet vorgeschlagen werden.

OPTION 1: Verwenden Apfel Erreichbarkeits Klasse

Mit Erreichbarkeits kann ich Internet-Konnektivität überprüfen, wie folgend, die kurz und direkt ist, und nicht für jede Antwort warten müssen.

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

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    if (![self connected]){ 
    // Not connected 
    }else{ 
    // Connected 
    } 

} 

Aber hier Internet Prüfung wird bei Pre-Flight getan, die sich gegen Vorschlag wie auf WWDC video gesehen von Apfel Ingenieur ist. Auch wenn Sie ReadMe.md überprüfen, wurde erwähnt, dass Erreichbarkeit IPv6 vollständig unterstützt. Aber wenn Methode ErreichbarkeitFürInternetConnection in Erreichbarkeit.m überprüft wird, haben sie sockaddr_in verwendet, sockaddr_in6 wurde nicht verwendet, was für IPv6-Netzwerk empfohlen wird. Also ich weiß nicht, ob es im IPv6-Netzwerk funktioniert.

OPTION 2: Verwenden Sie Alamofire

  • nur versuchen, eine Verbindung nach einem der stackoverflow answer zu verbinden. Der Code auch unten dargestellt: -

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

Aber ist es nicht Zeit, um zu versuchen raubend zu einem gewissen Host zu verbinden, für die Antwort warten und dann, wenn online/offline wissen.

OPTION 3: Verwenden Sie die Version Reachability von Tony Million. Der Autor hat jedoch davor gewarnt, dass die App abgelehnt wird.

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

Aber in dieser Option ist meine Frage, ist dies der richtige Ansatz Internet zu testen, indem http://google.com verbindet -: Ich kann dies als Code unten verwenden. Garantiert dies 100% ige Ergebnisse? Was ist, wenn Google nicht erreichbar ist? Wenn die App in einem Land verwendet wird, in dem google.com nicht erlaubt ist, was ist das Ergebnis?

So war ich in einem großen Dilemma, welche Option zu wählen, wenn diese Optionen der richtige Weg sind oder gibt es eine bessere Möglichkeit, Internet zu überprüfen, die 100% Ergebnisse garantiert und funktioniert sowohl in IPv4 und IPv6-Netzwerk. Kann mir jemand vorschlagen, welche Option besser ist oder sollte ich einen anderen Ansatz wählen, was ist der bessere Weg, dies zu erreichen?

Ihre Antwort wird sehr geschätzt.

+0

würde ich mit nativer Erreichbarkeit gehen. Deaktivieren Sie Option 3 automatisch wegen möglicher Zurückweisung. Option 2 könnte in Ordnung sein, wenn Sie Alamofire bereits verwenden. – tktsubota

+1

Eigentlich würde ich nur die richtigen REST-Aufrufe selbst machen, und wenn Sie einen Fehler für kein Internet erhalten, dann rufen Sie die Fallback-Methode. Es mit einer zufälligen Domain zu testen bringt dich nirgendwohin. – tktsubota

+0

Ja, das ist die empfohlene Methode. Weitere Informationen finden Sie unter "Ohne Preflight verbinden" unter https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingundPreparingfürIPv6Transition/UnderstandingandPreparingfürdieIPv6Transition.html. –

Antwort

5

Ich glaube, Sie auf diesen Link hilfreich finden: Network connection check crashing on IPv6 networks in 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 == .ConnectionRequired 

     return isReachable && !needsConnection 

    } 
} 

// Anwendungsfall

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

Hier sind ein paar andere Verbindungen für die Forschung:

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

+0

Ich musste diese Lösung auch verwenden. Aber wird dies auch für IPv6 funktionieren, da sockaddr_in gemäß diesem Dokument nur die IPv4-Umgebung behandelt [link] https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingforIPv6Transition/UnderstandingandPreparingforIPv6Transition.html – skJosh

+1

I Denken Sie daran, dass Sie die SCNetworkReachabilityCreateWithName-Methode anstelle von SCNetworkReachabilityCreateWithAddress untersuchen möchten. – Asdrubal

+0

@Asdrubal Funktioniert das sowohl für ipv4 als auch für ipv6? ohne ipv6 App Store Ablehnung? – iajmeri43

12

Für 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(.connectionRequired) 

    return (isReachable && !needsConnection) 
} 
0
  1. die von Github .zip Ordner herunterladen

  2. Dekomprimieren der Ordner angebracht und per Drag & Drop die Dateien in Ihre Projekt.

  3. Erstellen Sie eine Datei bridge.h und importieren Sie mit #import "Reachability.h".

  4. Bevor die API aufrufen, können Sie die Internet-Verbindung mit dem folgenden Code überprüfen:

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

Das ist es.

Verwandte Themen