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;
}
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
}
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
).
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
}
}
}
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()
Modifier NSAppTransportSecurity dans Info.plist:
Code:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>
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()
}
}
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
}
}
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
}
}
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)")
}
}
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
}
}