Check for internet connection with Swift

前端 未结 21 1525
别跟我提以往
别跟我提以往 2020-11-22 05:59

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
impo         


        
相关标签:
21条回答
  • 2020-11-22 06:09

    I have made my own solution using NSTimer and Alamofire:

    import Alamofire
    
    public class ConnectionHelper: NSObject {
        var request: Alamofire.Request?
    
        func isInternetConnected(completionHandler: Bool -> Void) {
            NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "requestTimeout", userInfo: nil, repeats: false)
    
            request = Alamofire
                .request(
                    Method.HEAD,
                    "http://www.testurl.com"
                )
                .response { response in
                    if response.3?.code == -999 {
                        completionHandler(
                            false
                        )
                    } else {
                        completionHandler(
                            true
                        )
                    }
            }
        }
    
        func requestTimeout() {
            request!.cancel()
        }
    }
    

    The NSTimer is used as a timeout, and was used due to unreliable results using the Alamofire timeout. The request should be made to a URL you trust to be reliable, such as your own server or the server that is hosting the services you depend on.

    When the timer expires, the request is cancelled and the results are returned using a completion handler.

    Usage:

    ConnectionHelper().isInternetConnected() { internetConnected in
        if internetConnected {
            // Connected
        } else {
            // Not connected
        }
    }
    
    0 讨论(0)
  • 2020-11-22 06:09

    here my solution for swift 2.3 with the lib (Reachability.swift)

    Go into your Podfile and add :

    pod 'ReachabilitySwift', '~> 2.4' // swift 2.3
    

    Then into your terminal :

    pod install
    

    Then create a new file ReachabilityManager and add code below :

    import Foundation
    import ReachabilitySwift
    
    enum ReachabilityManagerType {
        case Wifi
        case Cellular
        case None
    }
    
    class ReachabilityManager {
        static let sharedInstance = ReachabilityManager()
    
        private var reachability: Reachability!
        private var reachabilityManagerType: ReachabilityManagerType = .None
    
    
        private init() {
            do {
                self.reachability = try Reachability.reachabilityForInternetConnection()
            } catch {
                print("Unable to create Reachability")
                return
            }
    
            NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ReachabilityManager.reachabilityChanged(_:)),name: ReachabilityChangedNotification,object: self.reachability)
            do{
                try self.reachability.startNotifier()
            }catch{
                print("could not start reachability notifier")
            }
        }
    
        @objc private func reachabilityChanged(note: NSNotification) {
    
            let reachability = note.object as! Reachability
    
            if reachability.isReachable() {
                if reachability.isReachableViaWiFi() {
                    self.reachabilityManagerType = .Wifi
                } else {
                    self.reachabilityManagerType = .Cellular
                }
            } else {
                self.reachabilityManagerType = .None
            }
        }
    }
    
    extension ReachabilityManager {
    
        func isConnectedToNetwork() -> Bool {
            return reachabilityManagerType != .None
        }
    
    }
    

    How use it:

    go into your AppDelegate.swift and add the code below :

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
         ReachabilityManager.sharedInstance
    }
    

    Then when you want to check if the device is connected to internet do :

    if ReachabilityManager.sharedInstance.isConnectedToNetwork() {
       // Connected
    } else {
      // Not connected
    }
    
    0 讨论(0)
  • 2020-11-22 06:10

    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!")
    }
    
    0 讨论(0)
  • 2020-11-22 06:10

    Swift 5

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

    In any method use the below condition

    if currentReachabilityStatus == .notReachable {
        // Network Unavailable
     } else {
        // Network Available
     }
    
    0 讨论(0)
  • 2020-11-22 06:10

    This is my version. Essentially it doesn't bring anything new. I bound it to UIDevice.

    import UIKit
    import SystemConfiguration
    
    extension UIDevice {
    
        open class var isConnectedToNetwork: Bool {
            get {
                var zeroAddress = sockaddr_in()
                zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
                zeroAddress.sin_family = sa_family_t(AF_INET)
    
                guard
                    let defaultRouteReachability: SCNetworkReachability = withUnsafePointer(to: &zeroAddress, {
                        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                            SCNetworkReachabilityCreateWithAddress(nil, $0)
                        }
                    }),
                    var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags() as SCNetworkReachabilityFlags?,
                    SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags)
                    else { return false }
    
                return flags.contains(.reachable) && !flags.contains(.connectionRequired)
            }
        }
    
    }
    
    print("Network status availability: " + ( UIDevice.isConnectedToNetwork ? "true" : "false" ))
    
    0 讨论(0)
  • 2020-11-22 06:11

    For swift 3, I couldn't use just reachability from RAJAMOHAN-S solutions since it returns "true" if there is WiFi but no Internet. Thus, I implemented second validation via URLSession class and completion handler.

    Here is the whole 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(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
    }
    
    
    
    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()
    }
    }
    

    And you call this like this, for example:

    Reachability.isInternetAvailable(webSiteToPing: nil) { (isInternetAvailable) in
      guard isInternetAvailable else {
        // Inform user for example
        return
      }
    
      // Do some action if there is Internet
    }
    
    0 讨论(0)
提交回复
热议问题