Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reachability returns False for Cellular network in iOS - Swift

I have this code for checking internet connection , it was working very well until I update to Xcode 8 and swift 3 . Now it returns false for Cellular network and true for WiFi network I don't know why.

This is the code :

open 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
    }

    let isReachable = flags == .reachable
    let needsConnection = flags == .connectionRequired

    return isReachable && !needsConnection

  }
}

Now how to make this function return true for both wifi and cellular connection ?

like image 846
Zizoo Avatar asked Dec 24 '22 01:12

Zizoo


2 Answers

I'm using the following code and it's working perfect.

For Swift3

import Foundation
import SystemConfiguration

public 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) {
            $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)
    }

}

Called by:

if Reachability.isConnectedToNetwork() == true {
    xy
} else {
    yz
}

Swift 2 (for further spectators)

import Foundation
import SystemConfiguration

public class Reachability {

    class func isConnectedToNetwork() -> 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) {
            return false
        }

        let isReachable = flags.contains(.Reachable)
        let needsConnection = flags.contains(.ConnectionRequired)
        return (isReachable && !needsConnection)
    }
}

Same call as in Swift 3.

like image 159
David Seek Avatar answered Mar 07 '23 03:03

David Seek


This is a swift implementation of Apple's Reachability framework. Consider using it, this might solve your problem.Reachability

To check if the user is connected to a internet

let reachability = Reachability()
if reachability.isReachable{
//Network is reachable
}else{
//Not reachable 
}

It also has whenReachable,whenUnreachable closures and ReachabilityChangedNotification notification which you can use to check when the internet connection is available and when it is unavailable so you can handle these events accordingly

like image 21
nishith Singh Avatar answered Mar 07 '23 03:03

nishith Singh