4

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 ?

Zizoo
  • 1,694
  • 5
  • 20
  • 42
  • Please note that http://stackoverflow.com/a/25623647/1187415 has been updated for Swift 3 some time ago. – Martin R Sep 24 '16 at 11:27

2 Answers2

5

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

nishith Singh
  • 2,968
  • 1
  • 15
  • 25
  • Thank you , should I call this func `isReachable` ? there is a lot of code , what I want is to check if the user connected to any network nothing specific , can you tell what should I call ? – Zizoo Sep 24 '16 at 11:12
  • Updated my answer. Hope this helps – nishith Singh Sep 24 '16 at 11:22
5

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.

David Seek
  • 16,783
  • 19
  • 105
  • 136
  • 1
    are you using swift 3 ? .. I got this from your code `UnsafePointer($0)` : 'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type. – Zizoo Sep 24 '16 at 11:02
  • swift 2.3 ... I'm sorry my bad... guess this problem will annoy us the next weeks... I'm trying to translate it now... – David Seek Sep 24 '16 at 11:04
  • Thank you for your answer anyway – Zizoo Sep 24 '16 at 11:06
  • Thanks a lot for your help – Zizoo Sep 24 '16 at 11:17