Details
- Xcode 10.2.1 (10E1001), Swift 5
Prepare
Edit NSAppTransportSecurity in Info.plist:
Code:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>
Sample 1 (need Alamofire pod)
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()
}
}
Sample 2 (need 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
}
}
Sample 3 (without third party library)
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)")
}
}