iosswiftnetwork-connection

Check for internet connection availability in Swift


Is there a way to check if the internet connection is available using Swift?

I know there are many third party libraries to do this but they are all written in Objective-C. I'm looking for a Swift alternative.


Solution

  • As mentioned in the comments, although its possible to use Objective-C libraries in Swift, I wanted a more pure Swift solution. The existing Apple Reachability class and other third party libraries seemed to be too complicated for me to translate to Swift. I Googled some more and I came across this article which shows a simple method to check for network availability. I set out to translate this to Swift. I hit many snags but thanks to Martin R from StackOverflow, I managed to resolve them and finally get a workable solution in Swift. Here is the code.

    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(nil, UnsafePointer($0)).takeRetainedValue()
            }
    
            var flags: SCNetworkReachabilityFlags = 0
            if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == 0 {
                return false
            }
    
            let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0
            let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
    
            return isReachable && !needsConnection
        }
    
    }
    

    For Swift > 3.0

    public class Reachability {
        public 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
            }
            if flags.isEmpty {
                return false
            }
    
            let isReachable = flags.contains(.reachable)
            let needsConnection = flags.contains(.connectionRequired)
    
            return (isReachable && !needsConnection)
        }
    }
    

    This works for both 3G and WiFi connections. I've also uploaded it to my GitHub with a working example.