web-dev-qa-db-fra.com

Ne pas gérer d'erreur de connexion Internet avant d'essayer d'analyser le résultat dans Alamofire

Comment dois-je gérer en cas d'erreur se produit lorsqu'il n'y a pas de connexion Internet dans Alamofire. J'ai essayé de vérifier si les données sont nulles ou non, mais cela ne fonctionne pas.

Voici comment j'utilise Alamofire

Alamofire.request(.POST, REGISTER_URL, parameters: parameters, encoding: .JSON, headers: getAuthenticationHeader()).response { (request, response, data, errorType) -> Void in

    let resultObject: APIResults = APIResults(JSONDecoder(data!));
    let responseCode: Int = Int(resultObject.code!)!;// THIS CRASHES WHEN THERE IS NO INTERNET CONNECTION

    if (responseCode == 200) {
        available = true;
    }

    finished = true;

}
14
JayVDiyk

Je suis d'accord avec @Shripada. Vous devez d'abord utiliser l'accessibilité pour vérifier la connectivité. Il y a une bibliothèque Swift ici: https://github.com/ashleymills/Reachability.Swift

en outre, vous pouvez utiliser l'une des méthodes de validation Alamofire:

Alamofire.request(.POST, REGISTER_URL, parameters: parameters, encoding: .JSON, headers: getAuthenticationHeader()).validate(statusCode: 200 ..< 300).response { (request, response, data, error) -> Void in
    if error != nil {
        println("Server responded with: \(response.statusCode)")
        return
    }

    // Handle your response data here
}
4
ergoon

Solution Swift

En supposant que vous avez une instance Error, vous pouvez effectuer les opérations suivantes:

if let err = error as? URLError, err.code  == URLError.Code.notConnectedToInternet
{
    // No internet
}
else
{
    // Other errors
}

Vous transformez simplement error en URLError. Cela fonctionne puisque URLError implémente le protocole Error. Voici une citation de la documentation Apple pour référence:

URLError: décrit les erreurs dans le domaine d'erreur URL.

Une fois que vous avez une instance URLError, vous pouvez simplement comparer sa propriété code, qui est une URLError.Code enum, contre tous les cas d'énumération pertinents (dans notre exemple URLError.Code.notConnectedToInternet).

26
AndreasLukas

Cela fonctionne pour moi dans Swift2.x

Alamofire.request(.POST, url).responseJSON { response in
    switch response.result {
        case .Success(let json):
            // internet works.  
        case .Failure(let error):

            if let err = error as? NSURLError where err == .NotConnectedToInternet {
                // no internet connection
            } else {
                // other failures
            }
    }
}
11
Melvin

Autre moyen de vérifier la connexion Internet existante

import SystemConfiguration

func connectedToNetwork() -> Bool {

        var zeroAddress = sockaddr_in()    

       zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))

        zeroAddress.sin_family = sa_family_t(AF_INET)

      guard let defaultRouteReachability = withUnsafePointer(&zeroAddress, {
            SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
        }) else {
            return false
        }
        var flags : SCNetworkReachabilityFlags = []

        if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == false {

            return false

        }

        let isReachable = flags.contains(.Reachable)

        let needsConnection = flags.contains(.ConnectionRequired)

        return (isReachable && !needsConnection)

    }

let hasInternet = connectedToNetwork()
5
SwiftStudier

Détails

  • Xcode 10.2.1 (10E1001), Swift 5

Préparer

Modifier NSAppTransportSecurity dans Info.plist:

Code:

<key>NSAppTransportSecurity</key>
    <dict>
    <key>NSAllowsArbitraryLoads</key><true/>
</dict>

Exemple 1 (besoin Alamofire pod)

Utilisez Accessibilité résea

import UIKit
import Alamofire

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let button = UIButton(frame: .init(x: 80, y: 80, width: 100, height: 40))
        button.setTitle("Check", for: .normal)
        button.addTarget(self, action: #selector(checkInternetConnection), for: .touchUpInside)
        button.setTitleColor(.blue, for: .normal)
        view.addSubview(button)
    }

    @objc func checkInternetConnection() {
        guard let networkReachabilityManager = NetworkReachabilityManager(Host: "http://google.com") else { return }
        networkReachabilityManager.listener = { [weak self] status in
            let alert = UIAlertController(title: "Network Status ", message: "\(status)", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] _ in
                alert?.dismiss(animated: true, completion: nil)
            }))
            self?.present(alert, animated: true, completion: nil)
        }
        networkReachabilityManager.startListening()
    }
}

Exemple 2 (besoin Alamofire pod)

import UIKit
import Alamofire

class ViewController: UIViewController {

    private lazy var networkManager = NetworkManager()

    override func viewDidLoad() {
        super.viewDidLoad()
        let button = UIButton(frame: .init(x: 80, y: 80, width: 100, height: 40))
        button.setTitle("Check", for: .normal)
        button.addTarget(self, action: #selector(checkInternetConnection), for: .touchUpInside)
        button.setTitleColor(.blue, for: .normal)
        view.addSubview(button)
    }

    @objc func checkInternetConnection() {
        let urlString = "http://dummy.restapiexample.com/api/v1/employees"
        networkManager.sessionManager.request(urlString).validate().response { response in
            print("\(response.data as Any)")
        }
    }
}


class NetworkManager {
    lazy var sessionManager: SessionManager = {
        let configuration = URLSessionConfiguration.default
        configuration.httpCookieStorage = nil
        configuration.httpCookieAcceptPolicy = HTTPCookie.AcceptPolicy.never
        let manager = SessionManager(configuration: configuration)
        manager.retrier = self
        return manager
    }()
}

extension NetworkManager: RequestRetrier {
    func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
        let error = error as NSError
        switch error.code {
            case -1009:
                DispatchQueue.main.async {
                    let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
                    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] _ in
                        alert?.dismiss(animated: true, completion: nil)
                    }))
                    UIApplication.topMostViewController?.present(alert, animated: true, completion: nil)
                }
            default: break
        }
        print("-- Error code: \(error.code)")
        print("-- Error descriptiom: \(error.localizedDescription)")
    }
}


// https://stackoverflow.com/a/52932487
extension UIViewController {
    var topMostViewController: UIViewController {

        if let presented = self.presentedViewController {
            return presented.topMostViewController
        }

        if let navigation = self as? UINavigationController {
            return navigation.visibleViewController?.topMostViewController ?? navigation
        }

        if let tab = self as? UITabBarController {
            return tab.selectedViewController?.topMostViewController ?? tab
        }
        return self
    }
}

extension UIApplication {
    class var topMostViewController : UIViewController? {
        return UIApplication.shared.keyWindow?.rootViewController?.topMostViewController
    }
}

Exemple 3 (sans bibliothèque tierce)

Plus d'informations: Comment utiliser SCNetworkReachability dans Swift

import UIKit
import SystemConfiguration

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let button = UIButton(frame: .init(x: 80, y: 80, width: 100, height: 40))
        button.setTitle("Check", for: .normal)
        button.addTarget(self, action: #selector(checkInternetConnection), for: .touchUpInside)
        button.setTitleColor(.blue, for: .normal)
        view.addSubview(button)
    }

    @objc func checkInternetConnection() {
        print("-- \(URLSession.connectedToNetwork())")
    }
}

extension URLSession {
    class func connectedToNetwork() -> Bool {
        var zeroAddress = sockaddr()
        zeroAddress.sa_len = UInt8(MemoryLayout<sockaddr>.size)
        zeroAddress.sa_family = sa_family_t(AF_INET)
        guard let networkReachability = SCNetworkReachabilityCreateWithAddress(nil, &zeroAddress) else { return false }
        var flags = SCNetworkReachabilityFlags()
        SCNetworkReachabilitySetDispatchQueue(networkReachability, DispatchQueue.global(qos: .default))
        if SCNetworkReachabilityGetFlags(networkReachability, &flags) == false { return false }
        let isReachable = flags.contains(.reachable)
        let needsConnection = flags.contains(.connectionRequired)
        return isReachable && !needsConnection
    }
}

Exemple 4 (besoin Reachability.Swift pod)

import UIKit
import Reachability

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let button = UIButton(frame: .init(x: 80, y: 80, width: 100, height: 40))
        button.setTitle("Check", for: .normal)
        button.addTarget(self, action: #selector(checkInternetConnection), for: .touchUpInside)
        button.setTitleColor(.blue, for: .normal)
        view.addSubview(button)
    }

    @objc func checkInternetConnection() {
        guard let reachability = Reachability(hostname: "google.com", queueQoS: .utility) else { return }
        try? reachability.startNotifier()
        print("-- \(reachability.connection as Any)")
    }
}
3

Il fonctionne en Swift 5

.catchError { (error: Error) in
                    if let err = error as? URLError, err.code  == URLError.Code.notConnectedToInternet {
                        // No internet
                    } else {
                        // Other errors
                    }
                }
0
NSnik