Check internet connection (iOS 10)

Swift3Ios10Internet Connection

Swift3 Problem Overview


For iOS 9 I was using Reachability public class to check wether the device is connected to the internet or not. I converted my Swift 2 code to Swift 3, and the Reachability doesn't work anymore. Can someone tell me how to check the internet connection on iOS 10? Thanks! Here's the code snippet:

open class Reachability {
    class func isConnectedToNetwork() -> Bool {
        var zeroAddress = sockaddr_in()
        zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)
        let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
            SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
        }
        var flags = SCNetworkReachabilityFlags()
        if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
            return false
        }
        let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
        let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
        return (isReachable && !needsConnection)
    }
}

Swift3 Solutions


Solution 1 - Swift3

import Foundation
import SystemConfiguration

func isInternetAvailable() -> Bool
    {
        var zeroAddress = sockaddr_in()
        zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)
        
        let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
                SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
            }
        }
        
        var flags = SCNetworkReachabilityFlags()
        if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
            return false
        }
        let isReachable = flags.contains(.reachable)
        let needsConnection = flags.contains(.connectionRequired)
        return (isReachable && !needsConnection)
    }

This works in iOS 10

Solution 2 - Swift3

SWIFT 3.0: Here's very simple way to do it:

import SystemConfiguration


protocol Utilities {
}

extension NSObject:Utilities{
    
    
    enum ReachabilityStatus {
        case notReachable
        case reachableViaWWAN
        case reachableViaWiFi
    }

    var currentReachabilityStatus: ReachabilityStatus {
        
        var zeroAddress = sockaddr_in()
        zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
        zeroAddress.sin_family = sa_family_t(AF_INET)
        
        guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                SCNetworkReachabilityCreateWithAddress(nil, $0)
            }
        }) else {
            return .notReachable
        }
        
        var flags: SCNetworkReachabilityFlags = []
        if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
            return .notReachable
        }

        if flags.contains(.reachable) == false {
            // The target host is not reachable.
            return .notReachable
        }
        else if flags.contains(.isWWAN) == true {
            // WWAN connections are OK if the calling application is using the CFNetwork APIs.
            return .reachableViaWWAN
        }
        else if flags.contains(.connectionRequired) == false {
            // If the target host is reachable and no connection is required then we'll assume that you're on Wi-Fi...
            return .reachableViaWiFi
        }
        else if (flags.contains(.connectionOnDemand) == true || flags.contains(.connectionOnTraffic) == true) && flags.contains(.interventionRequired) == false {
            // The connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs and no [user] intervention is needed
            return .reachableViaWiFi
        } 
        else {
            return .notReachable
        }
    }
   
}

and then simply you can use it anywhere in your project for example:

  func viewDidLoad(){
      print(currentReachabilityStatus != .notReachable) //true connected
    }
     

Solution 3 - Swift3

Try this, it works for me first import the SystemConfiguration to your class.

import SystemConfiguration

And now implement bellow function.

func isConnectedToNetwork() -> Bool {
    
    var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)
    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
        }
    }
    
    var flags = SCNetworkReachabilityFlags()
    if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
        return false
    }
    let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
    let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0

    return (isReachable && !needsConnection)
    
}

Solution 4 - Swift3

step 1 : create a swift file in your project. i created "ConnectionCheck.swift"

step 2 : add this code in your "ConnectionCheck.swift" file and "import SystemConfiguration" file to your "ConnectionCheck.swift" and "ViewController.swift"

import Foundation
import SystemConfiguration
public class ConnectionCheck {

class func isConnectedToNetwork() -> Bool {
    
    var zeroAddress = sockaddr_in()
    zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
    zeroAddress.sin_family = sa_family_t(AF_INET)
    
    guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
            SCNetworkReachabilityCreateWithAddress(nil, $0)
        }
    }) else {
        return false
    }
    
    var flags: SCNetworkReachabilityFlags = []
    if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
        return false
    }
    
    let isReachable = flags.contains(.reachable)
    let needsConnection = flags.contains(.connectionRequired)
    
    return (isReachable && !needsConnection)
}

}

step 3 : Now in "ViewController.swift" use this code to check Network Reachability

if ConnectionCheck.isConnectedToNetwork() {
        print("Connected")
    }
    else{
        print("disConnected")
    }

Solution 5 - Swift3

This code would be helpful for you. it worked for me in Swift 4 and Xcode 9

Go to https://github.com/ashleymills/Reachability.swift/tree/master/Reachability and copy Reachability.swift file to your project

Vasil Nunev clearly explain this Reachability https://www.youtube.com/watch?v=wDZmz9IsB-8

class ViewController: UIViewController {
    
   let reachability = Reachability();
    override func viewDidLoad() {
        super.viewDidLoad()

        reachability?.whenReachable = { _ in
            
            DispatchQueue.main.async {
                self.view.backgroundColor = UIColor.green
            }
        }
        
        reachability?.whenUnreachable = { _ in
            DispatchQueue.main.async {
                self.view.backgroundColor = UIColor.red
            }
        }
        NotificationCenter.default.addObserver(self, selector: #selector(internetChanged), name: Notification.Name.reachabilityChanged , object: reachability)
        do{
            
            try reachability?.startNotifier()
        }catch{
            print("Could not start notifier:\(error)")
        }
    
    }

    @objc func internetChanged(note:Notification)  {
        let reachability  = note.object as! Reachability
        
        if reachability.connection != .none {
            
            if reachability.connection == .wifi{
                DispatchQueue.main.async {
                    self.view.backgroundColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
                }
            }else if reachability.connection == .cellular{
                DispatchQueue.main.async {
                    self.view.backgroundColor = #colorLiteral(red: 0.3647058904, green: 0.06666667014, blue: 0.9686274529, alpha: 1)
                }
            }
        }else{
            DispatchQueue.main.async {
                self.view.backgroundColor = #colorLiteral(red: 0.7450980544, green: 0.1568627506, blue: 0.07450980693, alpha: 1)
            }
        }
    }
}

Solution 6 - Swift3

Here is Swift 3 solution via callback function, isConnectedToNetwork() is taken from the solution by Yasin Ugurlu from above.

class func isInternetAvailable(webSiteToPing: String?, completionHandler: @escaping (Bool) -> Void) {

    // 1. Check the WiFi Connection
    guard isConnectedToNetwork() else {
      completionHandler(false)
      return
    }
    
    // 2. Check the Internet Connection
    var webAddress = "https://www.google.com" // Default Web Site
    if let _ = webSiteToPing {
      webAddress = webSiteToPing!
    }
    
    guard let url = URL(string: webAddress) else {
      completionHandler(false)
      print("could not create url from: \(webAddress)")
      return
    }
    
    let urlRequest = URLRequest(url: url)
    let session = URLSession.shared
    let task = session.dataTask(with: urlRequest, completionHandler: { (data, response, error) in
      if error != nil || response == nil {
        completionHandler(false)
      } else {
        completionHandler(true)
      }
    })
    
    task.resume()
  }

Solution 7 - Swift3

Swift 4 / Xcode 10:

I would combine two functions ( with a bit changes) are taken from the solutions by @Pavle Mijatovic and @Krutagn Patel (with thanks) to answer @Lance Samaria question. :)

I almost checked all the possibilities. (the code can be enhanced, but it works fine)

have a class as below:

import Foundation
import SystemConfiguration

public class ConnectionCheck {
    
    class func isConnectedToNetwork() -> Bool {
        
        var zeroAddress = sockaddr_in()
        zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
        zeroAddress.sin_family = sa_family_t(AF_INET)
        
        guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                SCNetworkReachabilityCreateWithAddress(nil, $0)
            }
        }) else {
            return false
        }
        
        var flags: SCNetworkReachabilityFlags = []
        if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
            return false
        }
        
        let isReachable = flags.contains(.reachable)
        let needsConnection = flags.contains(.connectionRequired)
        
        return (isReachable && !needsConnection)
    }
    
    
    class func isInternetAvailable(webSiteToPing: String?, completionHandler: @escaping (_ b: Bool) -> Void) {
        
        // 1. Check the WiFi Connection
        guard isConnectedToNetwork() else {
            completionHandler(false)
            return
        }
        
        // 2. Check the Internet Connection
        var webAddress = "https://www.google.com" // Default Web Site
        if let _ = webSiteToPing {
            webAddress = webSiteToPing!
        }
        
        guard let url = URL(string: webAddress) else {
            completionHandler(false)
            print("could not create url from: \(webAddress)")
            return
        }
        
        let urlRequest = URLRequest(url: url)
        let session = URLSession.shared
        let task = session.dataTask(with: urlRequest, completionHandler: { (data, response, error) in
            if error != nil || response == nil {
                completionHandler(false)
            } else {
                completionHandler(true)
            }
        })
        
        task.resume()
    }
}

use the below code where you need to check the Internet connection: for example, in appDelegate -> applicationDidBecomeActive function.

explanation: whenever completionHandler function (above) is called, the result (true or false) is passed to the below code as b. so if b is true you have the Internet connection.

let web : String? = "https://www.google.com"
ConnectionCheck.isInternetAvailable(webSiteToPing: web) { (b)  in
 print(b)
if b {
print("connected") // or do something here
    } else {
print("disconnected") // or do something here
}
}

Solution 8 - Swift3

You can use in swift 3

import SystemConfiguration

class Connection {
    
    class func isConnectedToNetwork() -> Bool {
        
        var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
        zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)
        
        let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
            SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, UnsafePointer($0))
        }
        
        var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
        if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
            return false
        }
        
        let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
        let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
        
        return isReachable && !needsConnection
        
    }
}

Solution 9 - Swift3

  1. Create a new Swift file within your project, name it “Reachability.swift”.

  2. Cut & paste the following code into it to create your class.

    import Foundation import SystemConfiguration

    public class Reachability {

    class func isConnectedToNetwork() -> Bool {

     var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
     zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
     zeroAddress.sin_family = sa_family_t(AF_INET)
     
     let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
         SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, UnsafePointer($0))
     }
     
     var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
     if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
         return false
     }
     
     let isReachable = flags == .Reachable
     let needsConnection = flags == .ConnectionRequired
     
     return isReachable && !needsConnection
     
      }
    

    }

  3. You can check internet connection anywhere in your project using this code:

    if Reachability.isConnectedToNetwork() == true { println("Internet connection OK") } else { println("Internet connection FAILED") }

4)If the user is not connected to the internet, you may want to show them an alert dialog to notify them.

if Reachability.isConnectedToNetwork() == true {
println("Internet connection OK")
} else {
println("Internet connection FAILED")
var alert = UIAlertView(title: "No Internet Connection", message: "Make sure your 
 device is connected to the internet.", delegate: nil, cancelButtonTitle: "OK")
alert.show()
}

Solution 10 - Swift3

Swift 4/Xcode 9+ (make Reachability.swift file):

public class Reachability {
    
    class func isConnectedToNetwork() -> Bool {
        
        var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
        zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)
        
        let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
                SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
            }
        }
        
        var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
        if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
            return false
        }
        
        // Working for Cellular and WIFI
        let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
        let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
        let ret = (isReachable && !needsConnection)
        
        return ret
        
    }
}

usage:

if Reachability.isConnectedToNetwork() {
// connected, do something
}

Solution 11 - Swift3

  1. Create a Swift file within your project, name it: Reachability.swift". then paste below code in this Reachability.swift file:-

     import Foundation
     
     import SystemConfiguration
     
     public class Reachability {
         
         class func isConnectedToNetwork() -> Bool {
             
             var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
             zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
             zeroAddress.sin_family = sa_family_t(AF_INET)
             
             let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
                 SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, UnsafePointer($0))
             }
             
             var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
             if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
                 return false
             }
             
             let isReachable = flags == .Reachable
             let needsConnection = flags == .ConnectionRequired
             
             return isReachable && !needsConnection
             
         }
     }
    

Then you can check the internet anywhere in the project using below code

  if Reachability.isConnectedToNetwork() == true {
        println("Internet connection OK")
    } else {
        println("Internet connection FAILED")
    }

Solution 12 - Swift3

Another solution for Swift 4.0. Not a big fan o IUO rather use a guard

 func isConnectedToNetwork() -> Bool {
    var zeroAddress = sockaddr_in()
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)
    
    guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
            SCNetworkReachabilityCreateWithAddress(nil, $0)
        }
    }) else {
        return false
    }
    
    var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
    if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == false {
        return false
    }
    
    let isReachable = flags == .reachable
    let needsConnection = flags == .connectionRequired
    return isReachable && !needsConnection
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLOLXDXPLOLView Question on Stackoverflow
Solution 1 - Swift3Adnan T.View Answer on Stackoverflow
Solution 2 - Swift3JadView Answer on Stackoverflow
Solution 3 - Swift3Patel JigarView Answer on Stackoverflow
Solution 4 - Swift3Krutagn PatelView Answer on Stackoverflow
Solution 5 - Swift3Junaid AliView Answer on Stackoverflow
Solution 6 - Swift3Pavle MijatovicView Answer on Stackoverflow
Solution 7 - Swift3FRIDDAYView Answer on Stackoverflow
Solution 8 - Swift3Yasin UgurluView Answer on Stackoverflow
Solution 9 - Swift3Sahil OmerView Answer on Stackoverflow
Solution 10 - Swift3itsmcghView Answer on Stackoverflow
Solution 11 - Swift3HarshitView Answer on Stackoverflow
Solution 12 - Swift3apinhoView Answer on Stackoverflow