Check for internet connection with Swift

前端 未结 21 1551
别跟我提以往
别跟我提以往 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:13

    With the help of below code you can check for internet Connection for both cellular network as well as for wifi. language - Swift 3.0

    import UIKit
    import Foundation
    import SystemConfiguration
    
    class NetworkConnection: UIViewController {
    
      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)
    
        guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
          $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
            SCNetworkReachabilityCreateWithAddress(nil, $0)
          }
        }) else {
          return false
        }
    
        var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
        if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == false {
          return false
        }
        let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
        let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
        return (isReachable && !needsConnection)
      }
    
      class func checkConnection(sender:UIViewController){
        if NetworkConnection.isConnectedToNetwork() == true {
          print("Connected to the internet")
          //  Do something
        } else {
          print("No internet connection")
          let alertController = UIAlertController(title: "No Internet Available", message: "", preferredStyle: UIAlertControllerStyle.alert)
          let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){(result:UIAlertAction) -> Void in
            return
          }
          alertController.addAction(okAction)
          sender.present(alertController, animated: true, completion: nil)
          //  Do something
        }
      }
    
    }
    
    0 讨论(0)
  • 2020-11-22 06:13

    here is the same code with accepted answer but I find it more useful for some cases to use closures

    import SystemConfiguration
    
    public class Reachability {
    
        class func isConnectedToNetwork(isConnected : (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 {
                isConnected(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)
    
            isConnected(ret)
        }
    }
    

    and here is how to use it:

    Reachability.isConnectedToNetwork { (isConnected) in
        if isConnected {
            //We have internet connection | get data from server
        } else {
            //We don't have internet connection | load from database 
        }
    }
    
    0 讨论(0)
  • 2020-11-22 06:15

    if your project has a target above or equal iOS 12 and uses combine you could use this little piece of code.

    import Combine
    import Network
    
    enum NerworkType {
        case wifi
        case cellular
        case loopBack
        case wired
        case other
    }
    
    protocol ReachabilityServiceContract {
        var reachabilityInfos: PassthroughSubject<NWPath, Never> { get set }
        var isNetworkAvailable: CurrentValueSubject<Bool, Never> { get set }
        var typeOfCurrentConnection: PassthroughSubject<NerworkType, Never> { get set }
    }
    
    final class ReachabilityService: ReachabilityServiceContract {
        var reachabilityInfos: PassthroughSubject<NWPath, Never> = .init()
        var isNetworkAvailable: CurrentValueSubject<Bool, Never> = .init(false)
        var typeOfCurrentConnection: PassthroughSubject<NerworkType, Never> = .init()
    
        private let monitor: NWPathMonitor
        private let backgroudQueue = DispatchQueue.global(qos: .background)
    
        init() {
            monitor = NWPathMonitor()
            setUp()
        }
    
        init(with interFaceType: NWInterface.InterfaceType) {
            monitor = NWPathMonitor(requiredInterfaceType: interFaceType)
            setUp()
        }
    
        deinit {
            monitor.cancel()
        }
    }
    
    private extension ReachabilityService {
        func setUp() {
        
            monitor.pathUpdateHandler = { [weak self] path in
                self?.reachabilityInfos.send(path)
                switch path.status {
                case .satisfied:
                    self?.isNetworkAvailable.send(true)
                case .unsatisfied, .requiresConnection:
                    self?.isNetworkAvailable.send(false)
                @unknown default:
                    self?.isNetworkAvailable.send(false)
                }
                if path.usesInterfaceType(.wifi) {
                    self?.typeOfCurrentConnection.send(.wifi)
                } else if path.usesInterfaceType(.cellular) {
                    self?.typeOfCurrentConnection.send(.cellular)
                } else if path.usesInterfaceType(.loopback) {
                    self?.typeOfCurrentConnection.send(.loopBack)
                } else if path.usesInterfaceType(.wiredEthernet) {
                    self?.typeOfCurrentConnection.send(.wired)
                } else if path.usesInterfaceType(.other) {
                    self?.typeOfCurrentConnection.send(.other)
                }
            }
        
            monitor.start(queue: backgroudQueue)
        }
    }
    

    Just subscribe to the variable you want to follow and you should be updated of any changes.

    0 讨论(0)
  • 2020-11-22 06:18

    Just figured this out for myself.

    Xcode: 7.3.1, iOS 9.3.3

    Using ashleymills/Reachability.swift as Reachability.swift in my project, I created the following function:

    func hasConnectivity() -> Bool {
        do {
            let reachability: Reachability = try Reachability.reachabilityForInternetConnection()
            let networkStatus: Int = reachability.currentReachabilityStatus.hashValue
    
            return (networkStatus != 0)
        }
        catch {
            // Handle error however you please
            return false
        }
    }
    

    Simply call hasConnectivity() where ever you need to check for a connection. This works for Wifi as well as Cellular.


    Adding ashleymills's Reachability.swift so people dont have to move between sites:

    Copyright (c) 2014, Ashley Mills
    All rights reserved.
    
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
    
    1. Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
    
    2. Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.
    
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.
    */
    
    // Reachability.swift version 2.2beta2
    
    import SystemConfiguration
    import Foundation
    
    public enum ReachabilityError: ErrorType {
        case FailedToCreateWithAddress(sockaddr_in)
        case FailedToCreateWithHostname(String)
        case UnableToSetCallback
        case UnableToSetDispatchQueue
    }
    
    public let ReachabilityChangedNotification = "ReachabilityChangedNotification"
    
    func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) {
        let reachability = Unmanaged<Reachability>.fromOpaque(COpaquePointer(info)).takeUnretainedValue()
    
        dispatch_async(dispatch_get_main_queue()) {
            reachability.reachabilityChanged(flags)
        }
    }
    
    
    public class Reachability: NSObject {
    
        public typealias NetworkReachable = (Reachability) -> ()
        public typealias NetworkUnreachable = (Reachability) -> ()
    
        public enum NetworkStatus: CustomStringConvertible {
    
            case NotReachable, ReachableViaWiFi, ReachableViaWWAN
    
            public var description: String {
                switch self {
                case .ReachableViaWWAN:
                    return "Cellular"
                case .ReachableViaWiFi:
                    return "WiFi"
                case .NotReachable:
                    return "No Connection"
                }
            }
        }
    
        // MARK: - *** Public properties ***
        public var whenReachable: NetworkReachable?
        public var whenUnreachable: NetworkUnreachable?
        public var reachableOnWWAN: Bool
        public var notificationCenter = NSNotificationCenter.defaultCenter()
    
        public var currentReachabilityStatus: NetworkStatus {
            if isReachable() {
                if isReachableViaWiFi() {
                    return .ReachableViaWiFi
                }
                if isRunningOnDevice {
                    return .ReachableViaWWAN
                }
            }
            return .NotReachable
        }
    
        public var currentReachabilityString: String {
            return "\(currentReachabilityStatus)"
        }
    
        private var previousFlags: SCNetworkReachabilityFlags?
    
        // MARK: - *** Initialisation methods ***
    
        required public init(reachabilityRef: SCNetworkReachability) {
            reachableOnWWAN = true
            self.reachabilityRef = reachabilityRef
        }
    
        public convenience init(hostname: String) throws {
    
            let nodename = (hostname as NSString).UTF8String
            guard let ref = SCNetworkReachabilityCreateWithName(nil, nodename) else { throw ReachabilityError.FailedToCreateWithHostname(hostname) }
    
            self.init(reachabilityRef: ref)
        }
    
        public class func reachabilityForInternetConnection() throws -> Reachability {
    
            var zeroAddress = sockaddr_in()
            zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
            zeroAddress.sin_family = sa_family_t(AF_INET)
    
            guard let ref = withUnsafePointer(&zeroAddress, {
                SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
            }) else { throw ReachabilityError.FailedToCreateWithAddress(zeroAddress) }
    
            return Reachability(reachabilityRef: ref)
        }
    
        public class func reachabilityForLocalWiFi() throws -> Reachability {
    
            var localWifiAddress: sockaddr_in = sockaddr_in(sin_len: __uint8_t(0), sin_family: sa_family_t(0), sin_port: in_port_t(0), sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
            localWifiAddress.sin_len = UInt8(sizeofValue(localWifiAddress))
            localWifiAddress.sin_family = sa_family_t(AF_INET)
    
            // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
            let address: UInt32 = 0xA9FE0000
            localWifiAddress.sin_addr.s_addr = in_addr_t(address.bigEndian)
    
            guard let ref = withUnsafePointer(&localWifiAddress, {
                SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
            }) else { throw ReachabilityError.FailedToCreateWithAddress(localWifiAddress) }
    
            return Reachability(reachabilityRef: ref)
        }
    
        // MARK: - *** Notifier methods ***
        public func startNotifier() throws {
    
            guard !notifierRunning else { return }
    
            var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
            context.info = UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque())
    
            if !SCNetworkReachabilitySetCallback(reachabilityRef!, callback, &context) {
                stopNotifier()
                throw ReachabilityError.UnableToSetCallback
            }
    
            if !SCNetworkReachabilitySetDispatchQueue(reachabilityRef!, reachabilitySerialQueue) {
                stopNotifier()
                throw ReachabilityError.UnableToSetDispatchQueue
            }
    
            // Perform an intial check
            dispatch_async(reachabilitySerialQueue) { () -> Void in
                let flags = self.reachabilityFlags
                self.reachabilityChanged(flags)
            }
    
            notifierRunning = true
        }
    
        public func stopNotifier() {
            defer { notifierRunning = false }
            guard let reachabilityRef = reachabilityRef else { return }
    
            SCNetworkReachabilitySetCallback(reachabilityRef, nil, nil)
            SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil)
        }
    
        // MARK: - *** Connection test methods ***
        public func isReachable() -> Bool {
            let flags = reachabilityFlags
            return isReachableWithFlags(flags)
        }
    
        public func isReachableViaWWAN() -> Bool {
    
            let flags = reachabilityFlags
    
            // Check we're not on the simulator, we're REACHABLE and check we're on WWAN
            return isRunningOnDevice && isReachable(flags) && isOnWWAN(flags)
        }
    
        public func isReachableViaWiFi() -> Bool {
    
            let flags = reachabilityFlags
    
            // Check we're reachable
            if !isReachable(flags) {
                return false
            }
    
            // Must be on WiFi if reachable but not on an iOS device (i.e. simulator)
            if !isRunningOnDevice {
                return true
            }
    
            // Check we're NOT on WWAN
            return !isOnWWAN(flags)
        }
    
        // MARK: - *** Private methods ***
        private var isRunningOnDevice: Bool = {
            #if (arch(i386) || arch(x86_64)) && os(iOS)
                return false
            #else
                return true
            #endif
        }()
    
        private var notifierRunning = false
        private var reachabilityRef: SCNetworkReachability?
        private let reachabilitySerialQueue = dispatch_queue_create("uk.co.ashleymills.reachability", DISPATCH_QUEUE_SERIAL)
    
        private func reachabilityChanged(flags: SCNetworkReachabilityFlags) {
    
            guard previousFlags != flags else { return }
    
            if isReachableWithFlags(flags) {
                if let block = whenReachable {
                    block(self)
                }
            } else {
                if let block = whenUnreachable {
                    block(self)
                }
            }
    
            notificationCenter.postNotificationName(ReachabilityChangedNotification, object:self)
    
            previousFlags = flags
        }
    
        private func isReachableWithFlags(flags: SCNetworkReachabilityFlags) -> Bool {
    
            if !isReachable(flags) {
                return false
            }
    
            if isConnectionRequiredOrTransient(flags) {
                return false
            }
    
            if isRunningOnDevice {
                if isOnWWAN(flags) && !reachableOnWWAN {
                    // We don't want to connect when on 3G.
                    return false
                }
            }
    
            return true
        }
    
        // WWAN may be available, but not active until a connection has been established.
        // WiFi may require a connection for VPN on Demand.
        private func isConnectionRequired() -> Bool {
            return connectionRequired()
        }
    
        private func connectionRequired() -> Bool {
            let flags = reachabilityFlags
            return isConnectionRequired(flags)
        }
    
        // Dynamic, on demand connection?
        private func isConnectionOnDemand() -> Bool {
            let flags = reachabilityFlags
            return isConnectionRequired(flags) && isConnectionOnTrafficOrDemand(flags)
        }
    
        // Is user intervention required?
        private func isInterventionRequired() -> Bool {
            let flags = reachabilityFlags
            return isConnectionRequired(flags) && isInterventionRequired(flags)
        }
    
        private func isOnWWAN(flags: SCNetworkReachabilityFlags) -> Bool {
            #if os(iOS)
                return flags.contains(.IsWWAN)
            #else
                return false
            #endif
        }
        private func isReachable(flags: SCNetworkReachabilityFlags) -> Bool {
            return flags.contains(.Reachable)
        }
        private func isConnectionRequired(flags: SCNetworkReachabilityFlags) -> Bool {
            return flags.contains(.ConnectionRequired)
        }
        private func isInterventionRequired(flags: SCNetworkReachabilityFlags) -> Bool {
            return flags.contains(.InterventionRequired)
        }
        private func isConnectionOnTraffic(flags: SCNetworkReachabilityFlags) -> Bool {
            return flags.contains(.ConnectionOnTraffic)
        }
        private func isConnectionOnDemand(flags: SCNetworkReachabilityFlags) -> Bool {
            return flags.contains(.ConnectionOnDemand)
        }
        func isConnectionOnTrafficOrDemand(flags: SCNetworkReachabilityFlags) -> Bool {
            return !flags.intersect([.ConnectionOnTraffic, .ConnectionOnDemand]).isEmpty
        }
        private func isTransientConnection(flags: SCNetworkReachabilityFlags) -> Bool {
            return flags.contains(.TransientConnection)
        }
        private func isLocalAddress(flags: SCNetworkReachabilityFlags) -> Bool {
            return flags.contains(.IsLocalAddress)
        }
        private func isDirect(flags: SCNetworkReachabilityFlags) -> Bool {
            return flags.contains(.IsDirect)
        }
        private func isConnectionRequiredOrTransient(flags: SCNetworkReachabilityFlags) -> Bool {
            let testcase:SCNetworkReachabilityFlags = [.ConnectionRequired, .TransientConnection]
            return flags.intersect(testcase) == testcase
        }
    
        private var reachabilityFlags: SCNetworkReachabilityFlags {
    
            guard let reachabilityRef = reachabilityRef else { return SCNetworkReachabilityFlags() }
    
            var flags = SCNetworkReachabilityFlags()
            let gotFlags = withUnsafeMutablePointer(&flags) {
                SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($0))
            }
    
            if gotFlags {
                return flags
            } else {
                return SCNetworkReachabilityFlags()
            }
        }
    
        override public var description: String {
    
            var W: String
            if isRunningOnDevice {
                W = isOnWWAN(reachabilityFlags) ? "W" : "-"
            } else {
                W = "X"
            }
            let R = isReachable(reachabilityFlags) ? "R" : "-"
            let c = isConnectionRequired(reachabilityFlags) ? "c" : "-"
            let t = isTransientConnection(reachabilityFlags) ? "t" : "-"
            let i = isInterventionRequired(reachabilityFlags) ? "i" : "-"
            let C = isConnectionOnTraffic(reachabilityFlags) ? "C" : "-"
            let D = isConnectionOnDemand(reachabilityFlags) ? "D" : "-"
            let l = isLocalAddress(reachabilityFlags) ? "l" : "-"
            let d = isDirect(reachabilityFlags) ? "d" : "-"
    
            return "\(W)\(R) \(c)\(t)\(i)\(C)\(D)\(l)\(d)"
        }
    
        deinit {
            stopNotifier()
    
            reachabilityRef = nil
            whenReachable = nil
            whenUnreachable = nil
        }
    }
    
    0 讨论(0)
  • 2020-11-22 06:19

    Use this for Swift-5+

    import Foundation
    import UIKit
    import SystemConfiguration
    
    public class InternetConnectionManager {
    
    
        private init() {
    
        }
    
        public static func isConnectedToNetwork() -> Bool {
    
            var zeroAddress = sockaddr_in()
            zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
            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
            }
            let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
            let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
            return (isReachable && !needsConnection)
        }
    
    }
    

    Usage:

    InternetConnectionManager.isConnectedToNetwork{
        print("Connected")
    }else{
        print("Not Connected")
    }
    

    Or Just use this framework for more Utilities: Link

    0 讨论(0)
  • 2020-11-22 06:21

    If you are using Alamofire, you can do something like this:

    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    configuration.timeoutIntervalForRequest = 15 //Set timeouts in sec
    configuration.timeoutIntervalForResource = 15
    
    let alamoFireManager = Alamofire.Manager(configuration:configuration)
    alamoFireManager?.request(.GET, "https://yourURL.com", parameters: headers, encoding: .URL)
                         .validate()
                                  .responseJSON { response in
    
                                    if let error = response.result.error {
                                       switch error.code{
                                        case -1001:
                                            print("Slow connection")
                                            return
                                        case -1009:
                                            print("No Connection!")
                                            return
                                        default: break
                                        }
                                    }
    
    0 讨论(0)
提交回复
热议问题