2017-03-14 5 views
1

Ich verwende AlamoreFire und überprüfe die Netzwerkerreichbarkeit in zwei der View-Controller der App in der viewDidAppear-Methode von beiden. Aber manchmal, wenn das Netzwerk gefunden wird, lädt die View-Controller-Sammlungsansicht zweimal. Ich vermute, dass die Erreichbarkeit vielleicht nur in der gesamten App an einem Ort stehen sollte.Prüfen auf Erreichbarkeit in ViewDidAppear oder AppDelegate?

Was ist die beste und sauberste Möglichkeit, die Erreichbarkeit zu implementieren, wenn Sie mehrere View-Controller überprüfen müssen? Ich möchte den NetworkReachabilityManager von AlamoFire verwenden.

+0

Sind Sie sicher, dass Sie keine Verdopplung an einem SchlussergebnisHandler haben? – Sethmr

+0

@ dkw5877 Ich weiß über die Klassen, meine Frage ist, wo im Code sollte es geeigneter sein, AppDelegate oder in jeder ViewDidAppear-Methode zu implementieren? – Giovanni

+0

Ich habe den @ Velix007-Ansatz in Apps verwendet, in denen ich keinen Offline-Modus hatte. Überwachen Sie die Statusänderungen im App-Delegaten und stellen Sie dann einen Controller für die Internetverbindungsansicht vom obersten View-Controller aus bereit. –

Antwort

0

Ich habe meine Methode unten. Um jedoch direkter auf Ihre Frage einzugehen, würde ich in keiner der beiden nach Verbindungen suchen.

Beispiel: Ich bekomme den ganzen Weg zum apps ersten Netzwerkanruf und dann mein WLAN einschalten.

Problem: Meine App schlägt fehl, obwohl nichts, das WLAN in der App benötigt wurde, verwendet wurde.

Meine Methode: Ich kann verstehen, auf der Anmeldeseite nach einer Netzwerkverbindung zu suchen, aber abgesehen davon würde ich es in Ihr Netzwerk einfügen. Wenn ein Netzwerkanruf fehlschlägt, überprüfen Sie die Verbindung und beziehen Sie sich dann auf den Benutzer, ob der Anruf wegen des Servers oder wegen des Netzwerks fehlgeschlagen ist.

Dies ist, was ich für Erreichbarkeits verwenden:

import Foundation 

/// This class is designed to check if the network is connected. 
open class Reachability { 

    /// This function will hit two urls that should never be totally down to see if the device is connected 
    /// If either url connects, this returns true 
    /// 
    /// - Parameter resultHandler: returns the result of the connection existing as a Bool in a resultHandler 
    class func isConnectedToNetwork(_ resultHandler: @escaping (_ isTrue: Bool) -> Void) { 
     let urlA = URL(string: "https://google.com/") 
     let urlB = URL(string: "https://baidu.com/") 

     Reachability.fetchURL(urlA!) { isTrue in 
      if isTrue { 
       print("NETWORK STATUS: \(isTrue)") 
       resultHandler(isTrue) 
      } else { 
       Reachability.fetchURL(urlB!, resultHandler: resultHandler) 
      } 
     } 
    } 

    /// Hits a URL in order to see if the device can connect to it 
    /// 
    /// - Parameters: 
    /// - url: the url to request 
    /// - resultHandler: returns whether the url was successfully retrieved or not 
    class func fetchURL(_ url:URL, resultHandler: @escaping (_ isTrue: Bool) -> Void) { 
     var request = URLRequest(url: url) 
     request.httpMethod = "HEAD" 
     request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData 
     request.timeoutInterval = 10.0 

     let session = URLSession(configuration: .default) 
     let dataTask = session.dataTask(with: request) { data, response, error in 
      if let httpResponse = response as? HTTPURLResponse { 
       if httpResponse.statusCode == 200 { 
        resultHandler(true) 
       } else { 
        resultHandler(false) 
       } 
      } else { 
       resultHandler(false) 
      } 
     } 
     dataTask.resume() 
    } 
} 

überall Dann in Code, den Sie es wie so nennen kann:

Reachability.isConnectedToNetwork() { isConnected in 
    if isConnected { 
     //Do something when connected 
    } else { 
     //Do something when not connected 
    } 
} 
+1

Das hat das OP nicht gefragt. Übrigens, wie überwachen Sie Änderungen am Netzwerkstatus? Wie würden Sie eine Benachrichtigung veröffentlichen, wenn sich diese ändert? –

+0

Ich überprüfe meine Netzwerkanrufe, damit ich dem Benutzer immer sagen kann, warum er fehlgeschlagen ist, wenn er fehlschlägt. Wenn ich entsprechend handeln muss, mache ich das zu diesem Zeitpunkt. – Sethmr

+0

Also, wenn Sie eine Tabellenansicht haben, würde es es für jede Zelle beim Laden überprüfen? –

1

Normalerweise mit Erreichbarkeits Sie irgendeine Art von Fehler Blick haben würde auf Oben auf dem Bildschirm, keine Sorge, wenn der Hintergrund versucht zu laden oder nicht.

einen Container Ansicht erstellen und in viewDidLoad()

if Reachability.isConnectedToNetwork() == true { 
     self.errorView.isHidden = true 
    } else { 
     self.errorView.isHidden = false 
    } 

das Ihr Problem löst und hilft bei der UX.

+0

Danke Velix007, tatsächlich stürzt meine App nicht ab, weil ich Alamofire.request (url) .validate() benutze und mich dort bereits einchecke. Ich könnte meinen Aktivitätsindikator mit einer errorView überlappen, wie Sie sagen. Ich war mir nur nicht sicher, ob es der "richtige" Weg war, es zu tun. – Giovanni

+0

Ich bin mir sicher, dass es gemischte Gefühle gibt, aber aus der Sicht von UX und meiner anständigen Erfahrung ist es gar nicht so schlimm, es ist besser, als dass der Nutzer denkt, die App sei durcheinander, weil ein Bildschirm 2x geladen wird , 3x. errorView ftw. – Velix007