How should I handle if there is an error occurs when there is no internet connection in Alamofire. I tried checking if data is nil or not but it does not work.
Below
This works for me in 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
}
}
}
Swift 5.0
You can check with NSURL-related Error Code
if error._code == NSURLErrorNotConnectedToInternet {
}
Or you can check with the code
if error._code == -1009 {
}
You can check other code on the developer site. https://developer.apple.com/documentation/foundation/1508628-url_loading_system_error_codes
Swift 3 Solution
Assuming you have an Error
instance you can do the following:
if let err = error as? URLError, err.code == URLError.Code.notConnectedToInternet
{
// No internet
}
else
{
// Other errors
}
You simply cast error
into a URLError
. This works since URLError
implements the Error
protocol. Here is a quote from the apple documentation for reference:
URLError: Describes errors in the URL error domain.
Once you have a URLError
instance you can simply compare its code
property, which is a URLError.Code
enum, against the any relevant enum cases (in our example URLError.Code.notConnectedToInternet
).
I agree with @Shripada. First you should use Reachability to check for connectivity. There is a Swift library here: https://github.com/ashleymills/Reachability.swift
additionally you can use one of the Alamofire validation methods:
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
}
It works in swift 5
.catchError { (error: Error) in
if let err = error as? URLError, err.code == URLError.Code.notConnectedToInternet {
// No internet
} else {
// Other errors
}
}
Edit NSAppTransportSecurity in Info.plist:
Code:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>
Use Network Reachability
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
}
}
More info: How to use SCNetworkReachability in 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)")
}
}