webentwicklung-frage-antwort-db.com.de

Bester Ansatz für die Überprüfung der Internetverbindung in iOS

Ich habe im Internet gesucht, um die beste Möglichkeit zu finden, nach Internetverbindungen in iOS zu suchen, die für IPv4- und IPv6-Netzwerkumgebungen geeignet sind. Ich habe festgestellt, dass es viele mögliche Antworten gibt, die jedoch sehr verwirrt sind. Was ich tun muss, ist folgendes:

   // Check for internet connection

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

Ich habe die folgenden Optionen gefunden, die im Internet vorgeschlagen werden.

OPTION 1:Apple Reachability-Klasse verwenden

Mit Reachability kann ich die Internet-Konnektivität als kurz und direkt prüfen und muss nicht auf eine Antwort warten.

 - (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 wird die Internetüberprüfung im Vorfeld durchgeführt, was dem Vorschlag von Apple Engineer auf WWDC-Video widerspricht. Wenn Sie ReadMe.md aktivieren, wurde bereits erwähnt, dass Reachability IPv6 vollständig unterstützt. Wenn jedoch die Methode reachabilityForInternetConnection in Reachability.m aktiviert ist, wurde sockaddr_in verwendet, wurde sockaddr_in6 nicht verwendet, was für IPv6-Netzwerke empfohlen wird. Ich weiß also nicht, ob es in einem IPv6-Netzwerk funktioniert.

OPTION 2: Mit Alamofire verbinden 

  • Versuchen Sie einfach, eine Verbindung wie in einer der Antworten von stackoverflow herzustellen. Der Code wird auch unten gezeigt: -

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

Es ist jedoch nicht zeitaufwändig, sich mit einem Host zu verbinden, auf die Antwort zu warten und dann zu wissen, ob online/offline ist. 

OPTION 3: Verwenden Sie Tony Millions Version von Reachability . Der Autor hat jedoch davor gewarnt, dass die App bei der Verwendung dieser App abgelehnt wird. Ich kann diesen Code wie folgt verwenden: -

// 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, meine Frage ist, ist dies der richtige Ansatz, um das Internet durch Verbindung von http://google.com zu testen. Garantiert dies 100% Ergebnisse? Was ist, wenn Google ausfällt? Wenn die App in einem Land verwendet wird, in dem google.com nicht zulässig ist, was ist das Ergebnis? 

Ich befand mich also in einem großen Dilemma, welche Option zu wählen ist, ob diese Optionen der richtige Weg sind oder ob es eine bessere Möglichkeit gibt, das Internet zu überprüfen. Kann mir jemand vorschlagen, welche Option besser ist, oder sollte ich mich für einen anderen Ansatz entscheiden? Was ist der bessere Weg, dies zu erreichen? 

Ihre Antwort wird sehr geschätzt.

8
skJosh

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

Ich denke, Sie finden diesen Link hilfreich: Überprüfung der Netzwerkverbindung in IPv6-Netzwerken 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 Links für die Forschung:

https://developer.Apple.com/reference/systemconfiguration/1514904-scnetworkreachabilitycreatewithnn

https://developer.Apple.com/library/prerelease/content/dokumentation/Networking/Conceptual/SystemConfigFrameworks/SC_Intro/SC_Intro.html#//Apple_ref/doc/uid/TP40001065

6
Asdrubal

Alamofire

Wenn Sie bereits Alamofire für alle RESTful Api verwenden, können Sie davon profitieren.

Sie können Ihrer App die folgende Klasse hinzufügen und MNNetworkUtils.main.isConnected() aufrufen, um ein boolesches Verhalten darüber zu erhalten, ob eine Verbindung besteht oder nicht.

#import Alamofire

class MNNetworkUtils {
  static let main = MNNetworkUtils()
  init() {
    manager = NetworkReachabilityManager(Host: "google.com")
    listenForReachability()
  }

  private let manager: NetworkReachabilityManager?
  private var reachable: Bool = false
  private func listenForReachability() {
    self.manager?.listener = { [unowned self] status in
      switch status {
      case .notReachable:
        self.reachable = false
      case .reachable(_), .unknown:
        self.reachable = true
      }
    }
    self.manager?.startListening()
  }

  func isConnected() -> Bool {
    return reachable
  }
}

Dies ist eine Einzelklasse. Jedes Mal, wenn der Benutzer das Netzwerk verbindet oder trennt, überschreibt er self.reachable richtig in true/false, da wir bei der Initialisierung des Singleton die NetworkReachabilityManager-Einstellung abhören.

Um die Erreichbarkeit zu überwachen, müssen Sie einen Host angeben. Zur Zeit verwende ich google.com. Sie können bei Bedarf zu einem anderen Host oder einem Ihrer Hosts wechseln.

Für die beste Vorgehensweise denke ich, wenn Sie bereits Alamofire verwenden dies kann die beste Vorgehensweise sein. Ich denke nicht, dass google.com überwacht wird, ist ein schlechtes Design. Fühlen Sie sich frei, mich zu korrigieren, wenn ich falsch liege.

1
nuynait
  1. Laden Sie den ZIP-Ordner von Github herunter.

  2. Entpacken Sie den angehängten Ordner und ziehen Sie die Dateien in Ihr Projekt. 

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

  4. Bevor Sie die API aufrufen, können Sie die Internetverbindung mit folgendem Code überprüfen: 

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

Das ist es.

0
Arshad Shaik