Check for internet connection with Swift

298,619

Solution 1

To solve the 4G issue mentioned in the comments I have used @AshleyMills reachability implementation as a reference and rewritten Reachability for Swift 3.1:

updated: Xcode 10.1 • Swift 4 or later


Reachability.swift file

import Foundation
import SystemConfiguration

class Reachability {
    var hostname: String?
    var isRunning = false
    var isReachableOnWWAN: Bool
    var reachability: SCNetworkReachability?
    var reachabilityFlags = SCNetworkReachabilityFlags()
    let reachabilitySerialQueue = DispatchQueue(label: "ReachabilityQueue")
    init(hostname: String) throws {
        guard let reachability = SCNetworkReachabilityCreateWithName(nil, hostname) else {
            throw Network.Error.failedToCreateWith(hostname)
        }
        self.reachability = reachability
        self.hostname = hostname
        isReachableOnWWAN = true
        try start()
    }
    init() throws {
        var zeroAddress = sockaddr_in()
        zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
        zeroAddress.sin_family = sa_family_t(AF_INET)
        guard let reachability = withUnsafePointer(to: &zeroAddress, {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                SCNetworkReachabilityCreateWithAddress(nil, $0)
            }
        }) else {
            throw Network.Error.failedToInitializeWith(zeroAddress)
        }
        self.reachability = reachability
        isReachableOnWWAN = true
        try start()
    }
    var status: Network.Status {
        return  !isConnectedToNetwork ? .unreachable :
                isReachableViaWiFi    ? .wifi :
                isRunningOnDevice     ? .wwan : .unreachable
    }
    var isRunningOnDevice: Bool = {
        #if targetEnvironment(simulator)
            return false
        #else
            return true
        #endif
    }()
    deinit { stop() }
}

extension Reachability {

    func start() throws {
        guard let reachability = reachability, !isRunning else { return }
        var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
        context.info = Unmanaged<Reachability>.passUnretained(self).toOpaque()
        guard SCNetworkReachabilitySetCallback(reachability, callout, &context) else { stop()
            throw Network.Error.failedToSetCallout
        }
        guard SCNetworkReachabilitySetDispatchQueue(reachability, reachabilitySerialQueue) else { stop()
            throw Network.Error.failedToSetDispatchQueue
        }
        reachabilitySerialQueue.async { self.flagsChanged() }
        isRunning = true
    }

    func stop() {
        defer { isRunning = false }
        guard let reachability = reachability else { return }
        SCNetworkReachabilitySetCallback(reachability, nil, nil)
        SCNetworkReachabilitySetDispatchQueue(reachability, nil)
        self.reachability = nil
    }

    var isConnectedToNetwork: Bool {
        return isReachable &&
               !isConnectionRequiredAndTransientConnection &&
               !(isRunningOnDevice && isWWAN && !isReachableOnWWAN)
    }

    var isReachableViaWiFi: Bool {
        return isReachable && isRunningOnDevice && !isWWAN
    }

    /// Flags that indicate the reachability of a network node name or address, including whether a connection is required, and whether some user intervention might be required when establishing a connection.
    var flags: SCNetworkReachabilityFlags? {
        guard let reachability = reachability else { return nil }
        var flags = SCNetworkReachabilityFlags()
        return withUnsafeMutablePointer(to: &flags) {
            SCNetworkReachabilityGetFlags(reachability, UnsafeMutablePointer($0))
            } ? flags : nil
    }

    /// compares the current flags with the previous flags and if changed posts a flagsChanged notification
    func flagsChanged() {
        guard let flags = flags, flags != reachabilityFlags else { return }
        reachabilityFlags = flags
        NotificationCenter.default.post(name: .flagsChanged, object: self)
    }

    /// The specified node name or address can be reached via a transient connection, such as PPP.
    var transientConnection: Bool { return flags?.contains(.transientConnection) == true }

    /// The specified node name or address can be reached using the current network configuration.
    var isReachable: Bool { return flags?.contains(.reachable) == true }

    /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set, the kSCNetworkReachabilityFlagsConnectionOnTraffic flag, kSCNetworkReachabilityFlagsConnectionOnDemand flag, or kSCNetworkReachabilityFlagsIsWWAN flag is also typically set to indicate the type of connection required. If the user must manually make the connection, the kSCNetworkReachabilityFlagsInterventionRequired flag is also set.
    var connectionRequired: Bool { return flags?.contains(.connectionRequired) == true }

    /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. Any traffic directed to the specified name or address will initiate the connection.
    var connectionOnTraffic: Bool { return flags?.contains(.connectionOnTraffic) == true }

    /// The specified node name or address can be reached using the current network configuration, but a connection must first be established.
    var interventionRequired: Bool { return flags?.contains(.interventionRequired) == true }

    /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. The connection will be established "On Demand" by the CFSocketStream programming interface (see CFStream Socket Additions for information on this). Other functions will not establish the connection.
    var connectionOnDemand: Bool { return flags?.contains(.connectionOnDemand) == true }

    /// The specified node name or address is one that is associated with a network interface on the current system.
    var isLocalAddress: Bool { return flags?.contains(.isLocalAddress) == true }

    /// Network traffic to the specified node name or address will not go through a gateway, but is routed directly to one of the interfaces in the system.
    var isDirect: Bool { return flags?.contains(.isDirect) == true }

    /// The specified node name or address can be reached via a cellular connection, such as EDGE or GPRS.
    var isWWAN: Bool { return flags?.contains(.isWWAN) == true }

    /// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set
    /// The specified node name or address can be reached via a transient connection, such as PPP.
    var isConnectionRequiredAndTransientConnection: Bool {
        return (flags?.intersection([.connectionRequired, .transientConnection]) == [.connectionRequired, .transientConnection]) == true
    }
}

func callout(reachability: SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) {
    guard let info = info else { return }
    DispatchQueue.main.async {
        Unmanaged<Reachability>
            .fromOpaque(info)
            .takeUnretainedValue()
            .flagsChanged()
    }
}

extension Notification.Name {
    static let flagsChanged = Notification.Name("FlagsChanged")
}

struct Network {
    static var reachability: Reachability!
    enum Status: String {
        case unreachable, wifi, wwan
    }
    enum Error: Swift.Error {
        case failedToSetCallout
        case failedToSetDispatchQueue
        case failedToCreateWith(String)
        case failedToInitializeWith(sockaddr_in)
    }
}

Usage

Initialize it in your AppDelegate.swift didFinishLaunchingWithOptions method and handle any errors that might occur:

import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        do {
            try Network.reachability = Reachability(hostname: "www.google.com")
        }
        catch {
            switch error as? Network.Error {
            case let .failedToCreateWith(hostname)?:
                print("Network error:\nFailed to create reachability object With host named:", hostname)
            case let .failedToInitializeWith(address)?:
                print("Network error:\nFailed to initialize reachability object With address:", address)
            case .failedToSetCallout?:
                print("Network error:\nFailed to set callout")
            case .failedToSetDispatchQueue?:
                print("Network error:\nFailed to set DispatchQueue")
            case .none:
                print(error)
            }
        }
        return true
    }
}

And a view controller sample:

import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default
            .addObserver(self,
                         selector: #selector(statusManager),
                         name: .flagsChanged,
                         object: nil)
        updateUserInterface()
    }
    func updateUserInterface() {
        switch Network.reachability.status {
        case .unreachable:
            view.backgroundColor = .red
        case .wwan:
            view.backgroundColor = .yellow
        case .wifi:
            view.backgroundColor = .green
        }
        print("Reachability Summary")
        print("Status:", Network.reachability.status)
        print("HostName:", Network.reachability.hostname ?? "nil")
        print("Reachable:", Network.reachability.isReachable)
        print("Wifi:", Network.reachability.isReachableViaWiFi)
    }
    @objc func statusManager(_ notification: Notification) {
        updateUserInterface()
    }
}

Sample Project

Solution 2

For Swift 3, Swift 4 (working with cellular and Wi-Fi):

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

        /* Only Working for WIFI
        let isReachable = flags == .reachable
        let needsConnection = flags == .connectionRequired

        return isReachable && !needsConnection
        */

        // 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(){
    print("Internet Connection Available!")
}else{
    print("Internet Connection not Available!")
}

Solution 3

If someone is already using Alamofire then -

struct Connectivity {
  static let sharedInstance = NetworkReachabilityManager()!
  static var isConnectedToInternet:Bool {
      return self.sharedInstance.isReachable
    }
}

Usage:

if Connectivity.isConnectedToInternet {
     print("Connected")
 } else {
     print("No Internet")
}

Solution 4

Create a new Swift file within your project, name it Reachability.swift. 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

    }
}

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

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

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

if Reachability.isConnectedToNetwork() {
    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()
}

Explanation:

We are making a reusable public class and a method which can be used anywhere in the project to check internet connectivity. We require adding Foundation and System Configuration frameworks.

In the public class Reachability, the method isConnectedToNetwork() -> Bool { } will return a bool value about internet connectivity. We use a if loop to perform required actions on case. I hope this is enough. Cheers!

Solution 5

Apple has introduced Network Framework in iOS12.

import Foundation
import Network

class NetworkReachability {

   var pathMonitor: NWPathMonitor!
   var path: NWPath?
   lazy var pathUpdateHandler: ((NWPath) -> Void) = { path in
    self.path = path
    if path.status == NWPath.Status.satisfied {
        print("Connected")
    } else if path.status == NWPath.Status.unsatisfied {
        print("unsatisfied")
    } else if path.status == NWPath.Status.requiresConnection {
        print("requiresConnection")
    } 
}

let backgroudQueue = DispatchQueue.global(qos: .background)

init() {
    pathMonitor = NWPathMonitor()
    pathMonitor.pathUpdateHandler = self.pathUpdateHandler
    pathMonitor.start(queue: backgroudQueue)
   } 

 func isNetworkAvailable() -> Bool {
        if let path = self.path {
           if path.status == NWPath.Status.satisfied {
            return true
          }
        }
       return false
   }
 }
Share:
298,619

Related videos on Youtube

b3rge
Author by

b3rge

Updated on July 08, 2022

Comments

  • b3rge
    b3rge almost 2 years

    When I try to check for an internet connection on my iPhone I get a bunch of errors. Can anyone help me to fix this?

    The code:

    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)
    
        let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
            SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
        }
    
        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) ? true : false
    }
    
    }
    

    The errors with the code:

    Errors

    If it is unreadable, error 1 says:

    'Int' is not convertible to 'SCNetworkReachabilityFlags'

    Error 2 & 3:

    Could not find an overload for 'init' that accepts the supplied arguments

  • Martin R
    Martin R about 9 years
    I hope that you do not mind, but the code from the question looked similar to what I had once suggested here: stackoverflow.com/a/25623647/1187415, so I have updated that answer to Swift 2 as well. – There are small differences though, note that instead of UInt32(flags.rawValue) one can use the new set-like interface of OptionSetType.
  • Leo Dabus
    Leo Dabus about 9 years
    flags.rawValue returns UInt32 so UInt32 is not needed also
  • Martin R
    Martin R about 9 years
    What I meant is let isReachable = flags.contains(.Reachable) as in stackoverflow.com/a/25623647/1187415 :)
  • Melvin
    Melvin almost 9 years
    You need to remove ` == 0` from the if SCNetworkReachabilityGetFlags(…) as xCode returns a Bool in it latest version.
  • Ramesh Lingappa
    Ramesh Lingappa almost 9 years
    this code always returns as false even though i have active internet connection
  • G.Abhisek
    G.Abhisek over 8 years
    When you are giving a solution,please try to explain it a bit. Giving solution is not important , but making your readers understand the solution & its concept is more important.
  • G.Abhisek
    G.Abhisek over 8 years
    I am new to iOS programming . Why do we need to initialise a C struct for the purpose. In which instances can we use C structures?
  • TechBee
    TechBee over 8 years
    What if the website server is down?
  • Mark Tickner
    Mark Tickner over 8 years
    Then requestTimeout() would be called after the specified timeout was reached
  • TechBee
    TechBee over 8 years
    Thanks Mark! Your approach should be generic!!
  • Mark Tickner
    Mark Tickner over 8 years
    In what way? The site that is used? The idea would be that the site used is one that your app is dependent on
  • Daniel Arantes Loverde
    Daniel Arantes Loverde over 8 years
    i put this on "viewdidload" only for test. I open app and OK, have internet, but when i shootdown my internet, it continues show me i have internet... this is persistent ? or i have to "call action" everytime ?
  • Jordan Smith
    Jordan Smith over 8 years
    @AlvinGeorge this does NOT work when connected to a cellular network. This only works when using wifi. To anyone else - you do not want to use this in your app! @ Alvin - can I suggest you update your answer, or remove it? With 19 up votes it is very misleading to other developers that could fall into the same trap.
  • Jordan Smith
    Jordan Smith over 8 years
    This is NOT correct as @NickM mentioned. WILL NOT WORK FOR CELLULAR CONNECTIONS. Don't use this. I'm surprised it has so many up votes, maybe this is new as of iOS 9... but I don't think so.
  • Alvin George
    Alvin George over 8 years
    @Jordan : This method is using default apple framework for network status. It may change with new iOS versions. So I recommend you to check and implement the Ashely Mill's Reachability class. I have done a dependency free implementation and shared the link above. Please have a look.
  • Nick M
    Nick M over 8 years
    Doesn't work on IOS9, found out the very hard way - app in store... so I guess even if it's not 100% accurate and it works for some, it's inconsistent at best, so whoever wants to take chances might also want to bet on some horse or doggie if they're feeling lucky.
  • Jordan Smith
    Jordan Smith over 8 years
    @NickM - that explains why so many up votes. @ Leo it might be a good idea to update your answer for iOS 9, to save other people stumbling into the same trap. I can confirm it doesn't work (at least in some situations) on iOS 9... changing to github.com/ashleymills/Reachability.swift works fine however.
  • Brian Birtle
    Brian Birtle over 8 years
    This also doesn't seem to work - I'm running on an iPhone 5 debugging with a USB cable and connected via 3G and isReachable comes back as false, even though I successfully use the 3G connection in other apps.
  • GoodSp33d
    GoodSp33d about 8 years
    Probably not a good idea to make a network connection and see if it comes back with a response or not. There are simply too many what if questions
  • user2363025
    user2363025 about 8 years
    @Jordan did you find an approach that does work in both cases i.e. wifi and cellular?
  • Zafer Celaloglu
    Zafer Celaloglu about 8 years
    this solution is not valid for cellular
  • Colin Basnett
    Colin Basnett almost 8 years
    @GoodSp33d This method is good for checking if a web service is running or not. You may have an internet connection, but if a web service is down, you may want to allow the app to behave as if they have no network connection (eg. working offline).
  • Steven B.
    Steven B. almost 8 years
    This does NOT detect when connected to cellular, only returns true if connected over Wifi
  • Ace Green
    Ace Green almost 8 years
    Swift 3 error: " 'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type." UnsafePointer has been renamed to UnsafeRawPointer as per github.com/apple/swift-evolution/blob/master/proposals/…
  • Ace Green
    Ace Green almost 8 years
    @LeoDabus I have seen that library, is that the recommended way going forward? If so, maybe edit your reply to include it
  • Ace Green
    Ace Green almost 8 years
    @LeoDabus doesn't look like your version is updated to beta 6??
  • Ace Green
    Ace Green almost 8 years
    No rush thanks for the effort. I updated yours as far as I could.. still some issues though dl.dropboxusercontent.com/u/8061535/Reachability.swift.zip
  • Ace Green
    Ace Green almost 8 years
    I did, hence the changes. What do you think I did? Change yours then complained it didn't work? :P
  • Ace Green
    Ace Green almost 8 years
    I'm not sure what you mean by that. But the Reachability.swift in the link you sent me doesnt work on beta 6. My changes are the Xcode suggested improvements, with 4 errors remaining. Like the use of UnsafePointer($0) which was the error I got with my own code when I first reached out here
  • Ace Green
    Ace Green almost 8 years
    Oh so you took out anyone function referring UnsafePointer which yes fixes the error in beta 6 but takes away necessary functionality. Unfortunately I need reachabilityForInternetConnection()
  • Leo Dabus
    Leo Dabus almost 8 years
    @AceGreen you don't need that and that was taken out by the author. Just use reachability = try Reachability() without any host
  • Ace Green
    Ace Green almost 8 years
    Yea I see it was taking out in the iOS10 branch
  • cmeadows
    cmeadows almost 8 years
    @Xitcod13 This would work with a 4G Network. That being said it is recommended NOT to test preflight. Handle the exception thrown in your attempt to connect instead of using a Reachability.swift test case.
  • AMAN77
    AMAN77 over 7 years
  • Alejandro Jiménez Agudo
    Alejandro Jiménez Agudo over 7 years
    This solution + CoreTelephony (CTTelephonyNetworkInfo().currentRadioAccessTechnology) are the best solution to get the current network type, and without needed to depend on third party libs.
  • Rajamohan S
    Rajamohan S over 7 years
    @AlejandroJiménezAgudo , Thank you for the info. i will try it :)
  • Famic Tech
    Famic Tech over 7 years
    Reachabilty.swift has issues with Swift 3
  • vaibhav
    vaibhav over 7 years
    this code doesnt check the internet connectivity if connected to wifi.
  • vaibhav
    vaibhav over 7 years
    @LeoDabus what i mean to say is the above code you have posted is only checking whether the wifi is connected to device whereas it doesn't checks the internet connectivity ultimately. Working with swift2 is not a issue :)
  • davidethell
    davidethell over 7 years
    Works well with the Swift 3, just change let reachability: Reachability = try Reachability.reachabilityForInternetConnection() to let reachability: Reachability = try Reachability()!
  • Learn2Code
    Learn2Code about 7 years
    In Step 4... the UIappViewController.swift, why do we need this class!?
  • Learn2Code
    Learn2Code about 7 years
    UIappViewController.swift does not work with UICollectionViewController, so if you have a View that is of UICollectionViewController , you cant inherit UIappViewController!?
  • Brian Bird
    Brian Bird about 7 years
    Works for Cellular and WiFi with swift 3.1! Works tested on iPhone 6 and 7. If Cellular Off I get "..Connection not Available". If I turn on airplane mode get the same "...not available". If I keep cellular off and turn on wifi I get ".. Connection Available" and finally if I turn wifi off and turn Cellular on I get ".. Connection Available". Note my Cellular connection is LTE
  • Timeless
    Timeless about 7 years
    I think #if (arch(i386) || arch(x86_64)) && os(iOS) should return true?
  • Chinthaka Devinda
    Chinthaka Devinda about 7 years
    Seems like its not really working on the ios 10 for 4G connection.
  • Leo Dabus
    Leo Dabus about 7 years
    @ChinthakaDevinda What do you mean ? There is a sample project that was fully tested in the bottom of the answer.
  • checklist
    checklist about 7 years
    Do NOT use this as Apple will not approve your app as it is not IPv6 compliant like this.
  • Lawrence Tan
    Lawrence Tan over 6 years
    Hi, this doesnt work on iOS 11, airplane mode on a physical device. When set to airplane mode, isReachable is still true... any idea why?
  • Rajamohan S
    Rajamohan S over 6 years
    @LawrenceTan, make sure your device not using Internet via USB
  • Lawrence Tan
    Lawrence Tan over 6 years
    @RAJAMOHAN-S yes its not, its still returning true without USB.
  • Lawrence Tan
    Lawrence Tan over 6 years
    @RAJAMOHAN-S, I forgot to mention, your VPN has to be on. then turn on airplane mode.
  • fespinozacast
    fespinozacast about 6 years
    from the Alamofire documentation: > The NetworkReachabilityManager class listens for reachability changes of hosts and addresses for both WWAN and WiFi network interfaces. > Reachability can be used to determine background information about why a network operation failed, or to retry network requests when a connection is established. It should not be used to prevent a user from initiating a network request, as it’s possible that an initial request may be required to establish reachability.
  • r3dm4n
    r3dm4n about 6 years
    This is working perfect for me in all scenarios. It's also tested with iOS 12 running on iPhone 6.
  • Nathan Barreto
    Nathan Barreto almost 6 years
    This doesn't work if I'm connected to a wifi network without internet connection
  • Rajamohan S
    Rajamohan S almost 6 years
    @NathanMartins, Unfortunately we can check flag this much only. You need to check URLConnection while connecting with Wi-Fi. I will update asap
  • Jack
    Jack almost 6 years
    @fespinozacast well you can check internet connection code in NetworkReachabilityManager.swift , which is totally fine :)
  • Shuvo Joseph
    Shuvo Joseph almost 6 years
    if (Network.reachability?.isConnectedToNetwork)! {print("Call API")}
  • Shuvo Joseph
    Shuvo Joseph almost 6 years
    @LeoDabus Thanks for the code. Most user might not need to use the NotificationCenter and observe the status! They might just need to check if internet is available like me and then call api.
  • meow2x
    meow2x over 5 years
    You don't need to use the equality operator when a function returns a Bool. You don't need to say Reachability.isConnectedToNetwork() == true because the function itself returns a bool already.
  • Dave Levy
    Dave Levy over 5 years
    I wonder if anyone has augmented this code to check if a site is reachable? For instance, users might have a network connection but have yet to agree to the terms and conditions popup that the network requires before accessing any websites off the lan.
  • user924
    user924 over 5 years
    where should I put func callout(reachability: SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) { and other small stuff?
  • Leo Dabus
    Leo Dabus over 5 years
    @user924 there is a sample project link at the bottom of the answer. You can putt it all in the same file Reachability.swift
  • user924
    user924 over 5 years
    @LeoDabus thanks. .wwan is Cellular network connection?
  • Leo Dabus
    Leo Dabus over 5 years
    green means wifi connection, yellow means celular, red means no connection
  • user924
    user924 over 5 years
    @LeoDabus if Network.reachability.status == .unreachable { crashes with Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
  • Leo Dabus
    Leo Dabus over 5 years
    Have you ever initialised Network.reachability? You need to do first do { try Network.reachability = Reachability(hostname: "www.yourApiDomain.com")
  • user924
    user924 over 5 years
    @LeoDabus do I have to set some site address to check if I have wifi connection?
  • Leo Dabus
    Leo Dabus over 5 years
    You don't. The kind of connection it is not related at all. But you can use try Network.reachability = Reachability() as well
  • user924
    user924 over 5 years
    @LeoDabus then I think it's better to remove this parameter from constructor. Some developers can still add it and there can be situations when specific host isn't accessible in some countries or by some internet providers
  • Leo Dabus
    Leo Dabus over 5 years
    @user924 I don’t know what you mean by removing the parameter. There is two initializers. Use the one that fits your purpose. You can also delete the other one which you don’t need.
  • user924
    user924 over 5 years
    @LeoDabus I tried try Network.reachability = Reachability() and iPhone Simulator says that I don't have connection even though the connection is ok, condition Network.reachability?.status == .unreachable is true
  • Leo Dabus
    Leo Dabus over 5 years
    You need to test it in a real device
  • user924
    user924 over 5 years
    @LeoDabus it is so difficult and weird after Android. In Android emulators standard tiny method to check internet connection works fine. If I don't pass any host for Reachability() will it work ok everywhere? I don't want to set www.google.com because it's blocked in China, for example... It would be really bad if user has connection but our app failed to detect because such host isn't accessible for that user
  • Vitya Shurapov
    Vitya Shurapov about 5 years
    var path: NWPath? is nil. How do we initialize this property?
  • Yogendra Singh
    Yogendra Singh about 5 years
    @VityaShurapov By assigning path you are getting in pathUpdateHandler block.
  • zaitsman
    zaitsman about 5 years
    This looks fancy but i found (at least on the simulator) that if i switch my laptop wifi off then on, i get a callback but it says 'unsatisfied', and after that the callback is never invoked.
  • geohei
    geohei almost 5 years
    When cellular cycles on/off, the handler only triggers once for on/off. When WiFi cycles on/off, I get 2 identical triggers for on/off (all properties are identical). Why is that?
  • Andrea de Marco
    Andrea de Marco over 4 years
    pathUpdateHandler will introduce a strong reference with self, add [weak self] to solve it :)
  • RJB
    RJB over 4 years
    Dont forget import SystemConfiguration
  • Jamil Hasnine Tamim
    Jamil Hasnine Tamim over 4 years
    @DocAsh59 :) Welcome! Happy coding!
  • Roland Lariotte
    Roland Lariotte about 4 years
    I don't understand the usage of it. The compiler shows an error "Arguments passed to call that takes no arguments".
  • Jamil Hasnine Tamim
    Jamil Hasnine Tamim about 4 years
    @RolandLariotte You just class in your project named - "InternetConnectionManager", and then call from where you want!
  • Roland Lariotte
    Roland Lariotte about 4 years
    Works perfectly. Do you think this code can be more reactive by using Combine and returning an AnyPublisher<Bool, Never>? Could you write it this way?
  • Jamil Hasnine Tamim
    Jamil Hasnine Tamim about 4 years
    @RolandLariotte Yeah could be. I will write another code later. Thanks and don't forget to support! :)
  • agirault
    agirault almost 4 years
    How can I define the hostname to use with NWPathMonitor? I want to do what Reachability.reachabilityWithHostName did.
  • Dharmendra Kumar Rajan
    Dharmendra Kumar Rajan almost 4 years
    It's not working for mobile data in iOS 14 & above.
  • Dharmendra Kumar Rajan
    Dharmendra Kumar Rajan almost 4 years
    It's not working for mobile data in iOS 14 & above.
  • Dharmendra Kumar Rajan
    Dharmendra Kumar Rajan almost 4 years
    It's not working for mobile data in iOS 14 & above.
  • Dharmendra Kumar Rajan
    Dharmendra Kumar Rajan almost 4 years
    It's not working for mobile data in iOS 14 & above.
  • Dharmendra Kumar Rajan
    Dharmendra Kumar Rajan almost 4 years
    It's not working for mobile data in iOS 14 & above.
  • Pressing_Keys_24_7
    Pressing_Keys_24_7 over 3 years
    @DharmendraKumarRajan did you found any other solution?
  • Ronak Patel
    Ronak Patel over 3 years
    @NathanBarreto I'm also facing this same issue, is there any solution for this or not?
  • Nathan Barreto
    Nathan Barreto over 3 years
    @RonakPatel at that time I was using Alamofire, and I think the NetworkReachabilityManager mentioned in below anwsers helped me. I honestly dont remember what was the solution
  • Ronak Patel
    Ronak Patel over 3 years
    @NathanBarreto I tried the below option still facing the issue.
  • VyacheslavBakinkskiy
    VyacheslavBakinkskiy over 3 years
    Best solution! Thanks!
  • Neloy Kundu
    Neloy Kundu over 3 years
    @Flash Look at this link--> It works with current versions of Swift... hackingwithswift.com/example-code/networking/…
  • Jamil Hasnine Tamim
    Jamil Hasnine Tamim over 3 years
    @DharmendraKumarRajan great to know.
  • Markv07
    Markv07 over 3 years
    As others have indicated above, this method does not update constantly so if the connection is restored, the check will contine to be false for a while. To get around this, the .cancel() may be used when dismissing or navigating off the view, then it will be reinitiated when returning(if used in viewDidLoad). The good thing is that if the connection is lost after initiating, the hasConnectionPath appears to change immediately. So if you are protecting from a crash, this does the job.
  • skymook
    skymook over 3 years
    I have not experienced the delay myself. I keep alive my implementation of pathUpdateHandler, and other variables above, in a singleton that is always available. I wonder, @Markv07 if your pathUpdateHandler closure is being destroyed and recreated? The first time you create the pathUpdateHandler takes a little while.
  • PaianuVlad23
    PaianuVlad23 over 3 years
    This is by far the best solution here and works perfectly in both cases for me, thank you very much!
  • hbtpoprock
    hbtpoprock about 3 years
    This is awesome
  • inexcitus
    inexcitus almost 3 years
    This does exactly what I want. Thanks.
  • M Hamayun zeb
    M Hamayun zeb over 2 years
    Outstanding working for me......
  • iCediCe
    iCediCe over 2 years
    Making it a singleton seems like a poor choice, this is going to be hard to test. I would remove the private init. You can keep the shared instance for convenience though.
  • Muhammad Hasan Irshad
    Muhammad Hasan Irshad over 2 years
    It's a good solution but It give response twice. Any Idea why n how I can get rid oof it?
  • Muhammad Hasan Irshad
    Muhammad Hasan Irshad over 2 years
    This method doesn't work when app move from background (with no internet) to foreground and then turning on internet.
  • Lex
    Lex about 2 years
    I have checked, however in my code it only turns up once. Did you put the code in didFinishLaunchinWithOptions? Could you perhaps share some debug output?
  • Muhammad Hasan Irshad
    Muhammad Hasan Irshad about 2 years
    Yes I did add that idFinishLaunchinWithOptions?.
  • Sanjeevcn
    Sanjeevcn about 2 years
    Hi, is there anyway I can find out cellular connection type e.g 3G/4G etc..? Thanks
  • Lucas
    Lucas about 2 years
    Thanks for this Olcay! I've been using this code in production and Crashlytics indicates an inconsistant crash for a few of our users on the setUp() function