ios 在 Swift 中检查互联网连接的可用性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25398664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:57:13  来源:igfitidea点击:

Check for internet connection availability in Swift

iosswiftnetwork-connection

提问by Isuru

Is there a way to check if the internet connection is available using Swift?

有没有办法使用 Swift 检查互联网连接是否可用?

I know there are many third party libraries to do this but they are all written in Objective-C. I'm looking for a Swift alternative.

我知道有很多第三方库可以做到这一点,但它们都是用 Objective-C 编写的。我正在寻找 Swift 的替代品。

回答by Isuru

As mentioned in the comments, although its possible to use Objective-C libraries in Swift, I wanted a more pure Swift solution. The existing Apple Reachability class and other third party libraries seemed to be too complicated for me to translate to Swift. I Googled some more and I came across this articlewhich shows a simple method to check for network availability. I set out to translate this to Swift. I hit many snagsbut thanks to Martin Rfrom StackOverflow, I managed to resolve them and finally get a workable solution in Swift. Here is the code.

正如评论中提到的,虽然可以在 Swift 中使用 Objective-C 库,但我想要一个更纯粹的 Swift 解决方案。现有的 Apple Reachability 类和其他第三方库似乎太复杂了,我无法转换为 Swift。我在谷歌上搜索了更多,我看到了这篇文章,它展示了一种检查网络可用性的简单方法。我开始将其翻译成 Swift。我打了许多碰壁,但由于马丁- [R从StackOverflow的,我设法解决这些问题终于得到斯威夫特一个可行的解决方案。这是代码。

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(nil, UnsafePointer(
public class Reachability {
    public func isConnectedToNetwork() -> Bool {
        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, {
            
 import Foundation
 public class Reachability {

class func isConnectedToNetwork()->Bool{

    var Status:Bool = false
    let url = NSURL(string: "http://google.com/")
    let request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "HEAD"
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
    request.timeoutInterval = 10.0

    var response: NSURLResponse?

    var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: nil) as NSData?

    if let httpResponse = response as? NSHTTPURLResponse {
        if httpResponse.statusCode == 200 {
            Status = true
        }
    }

    return Status
  }
}
.withMemoryRebound(to: sockaddr.self, capacity: 1) { SCNetworkReachabilityCreateWithAddress(nil,
if Reachability.isConnectedToNetwork() == true {
     println("Internet connection OK")
} else {
     println("Internet connection FAILED")
}
) } }) else { return false } var flags: SCNetworkReachabilityFlags = [] if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) { return false } if flags.isEmpty { return false } let isReachable = flags.contains(.reachable) let needsConnection = flags.contains(.connectionRequired) return (isReachable && !needsConnection) } }
)).takeRetainedValue() } 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 } }

For Swift > 3.0

对于 Swift > 3.0

func checkWiFi() -> Bool {

    let networkStatus = Reachability().connectionStatus()
    switch networkStatus {
    case .Unknown, .Offline:
        return false
    case .Online(.WWAN):
        print("Connected via WWAN")
        return true
    case .Online(.WiFi):
        print("Connected via WiFi")
        return true
    }
}

This works for both 3G and WiFi connections. I've also uploaded it to my GitHubwith a working example.

这适用于 3G 和 WiFi 连接。我还用一个工作示例将它上传到了我的GitHub

回答by Dmitry

I give you better way...

我给你更好的方法...

You must create a class with this code

您必须使用此代码创建一个类

import Foundation
import SystemConfiguration

import UIKit
import SystemConfiguration.CaptiveNetwork

public let ReachabilityStatusChangedNotification = "ReachabilityStatusChangedNotification"

public enum ReachabilityType: CustomStringConvertible {
    case WWAN
    case WiFi

    public var description: String {
        switch self {
        case .WWAN: return "WWAN"
        case .WiFi: return "WiFi"
        }
    }
}

public enum ReachabilityStatus: CustomStringConvertible  {
    case Offline
    case Online(ReachabilityType)
    case Unknown

    public var description: String {
        switch self {
        case .Offline: return "Offline"
        case .Online(let type): return "Online (\(type))"
        case .Unknown: return "Unknown"
        }
    }
}

public class Reachability {

    func connectionStatus() -> ReachabilityStatus {
        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) {
            
import Foundation
import SystemConfiguration

public class Reachability {
    public func isConnectedToNetwork() -> Bool {
        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, {
            
if Reachability.isConnectedToNetwork() == true {
    print("Connected to the internet")
    //  Do something
} else {
    print("No internet connection")
    //  Do something
}
.withMemoryRebound(to: sockaddr.self, capacity: 1) { SCNetworkReachabilityCreateWithAddress(nil,
import Foundation

public class Reachability {

    class func isConnectedToNetwork()->Bool{

        var Status:Bool = false
        let url = NSURL(string: "http://google.com/")
        let request = NSMutableURLRequest(URL: url!)
        request.HTTPMethod = "HEAD"
        request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
        request.timeoutInterval = 10.0
        let session = NSURLSession.sharedSession()

        session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
            print("data \(data)")
            print("response \(response)")
            print("error \(error)")

            if let httpResponse = response as? NSHTTPURLResponse {
                print("httpResponse.statusCode \(httpResponse.statusCode)")
                if httpResponse.statusCode == 200 {
                    Status = true
                }
            }

        }).resume()


        return Status
    }
}
) } }) 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) } }
.withMemoryRebound(to: sockaddr.self, capacity: 1) { zeroSockAddress in SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress) } }) else { return .Unknown } var flags : SCNetworkReachabilityFlags = [] if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) { return .Unknown } return ReachabilityStatus(reachabilityFlags: flags) } func monitorReachabilityChanges() { let host = "google.com" var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil) let reachability = SCNetworkReachabilityCreateWithName(nil, host)! SCNetworkReachabilitySetCallback(reachability, { (_, flags, _) in let status = ReachabilityStatus(reachabilityFlags: flags) NotificationCenter.default.post(name: NSNotification.Name(rawValue: ReachabilityStatusChangedNotification), object: nil, userInfo: ["Status": status.description])}, &context) SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), CFRunLoopMode.commonModes.rawValue) } } extension ReachabilityStatus { public init(reachabilityFlags flags: SCNetworkReachabilityFlags) { let connectionRequired = flags.contains(.connectionRequired) let isReachable = flags.contains(.reachable) let isWWAN = flags.contains(.isWWAN) if !connectionRequired && isReachable { if isWWAN { self = .Online(.WWAN) } else { self = .Online(.WiFi) } } else { self = .Offline } } }

And then you can check internet connection anywhere in your project using this code:

然后您可以使用以下代码检查项目中任何位置的互联网连接:

    func checkInternet(flag:Bool, completionHandler:(internet:Bool) -> Void)
    {
      UIApplication.sharedApplication().networkActivityIndicatorVisible = true

      let url = NSURL(string: "http://www.google.com/")
      let request = NSMutableURLRequest(URL: url!)

      request.HTTPMethod = "HEAD"
      request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
      request.timeoutInterval = 10.0

      NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.mainQueue(), completionHandler:
      {(response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in

        UIApplication.sharedApplication().networkActivityIndicatorVisible = false

        let rsp = response as NSHTTPURLResponse?

        completionHandler(internet:rsp?.statusCode == 200)
    })
    }

     func yourMethod()
    {
    self.checkInternet(false, completionHandler:
    {(internet:Bool) -> Void in

        if (internet)
        {
            // "Internet" mean Google
        }
        else
        {
            // No "Internet" no Google
        }
    })
   }

Very easy!

好简单!

*This way is based on Vikram Pote answer!

*这种方式基于 Vikram Pote 的回答!

回答by iKK

For Swift 3.1 (iOS 10.1)

对于 Swift 3.1 (iOS 10.1)

If you want to make the distinction between the network-type (i.e. WiFi or WWAN):

如果要区分网络类型(即 WiFi 或 WWAN):

You can use:

您可以使用:

if isInternetAvailable() {
    print("if called Internet Connectivity success \(isInternetAvailable())");
} else {
    print("else called Internet Connectivity success \(isInternetAvailable())");
}

func isInternetAvailable() -> 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) {
        
import Network
let monitor = NWPathMonitor()

func checkInterwebs() -> Bool {
    var status = false
    monitor.pathUpdateHandler = { path in
        if path.status == .satisfied {
            status = true  // online
        }
    }
    return status
}
.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) // print(isReachable && !needsConnection) return (isReachable && !needsConnection) }

Here is the entire Reachability-Class that distinguished between network-types:

这是区分网络类型的整个 Reachability-Class:

DispatchQueue.main.async {
        let url = URL(string: "https://www.google.com")!
        let request = URLRequest(url: url)

        let task = URLSession.shared.dataTask(with: request) {data, response, error in

            if error != nil {
                // do something here...
                print("Internet Connection not Available!")
            }
            else if let httpResponse = response as? HTTPURLResponse {
                if httpResponse.statusCode == 200 {
                    // do something here...
                    print("Internet Connection OK")
                }
                print("statusCode: \(httpResponse.statusCode)")
            }

        }
        task.resume()
}

回答by Gilad Brunfman

SWIFT 3:Checks for wifiand internetconnection:

SWIFT 3:检查wifi互联网连接:

##代码##

USAGE:

用法:

##代码##

回答by Sarah

Since sendSynchronousRequest is deprecated, I tried this but 'return Status' was called before the response had finished.

由于不推荐使用 sendSynchronousRequest,因此我尝试了此操作,但在响应完成之前调用了“返回状态”。

This answer works well though, Check for internet connection with Swift

不过,这个答案效果很好,请检查与 Swift 的互联网连接

Here's what I tried anyway:

无论如何,这就是我尝试过的:

##代码##

回答by Vikram Pote

You can also use below answer.

您也可以使用以下答案。

##代码##

回答by Keshav Gera

Swift 4

斯威夫特 4

##代码##

回答by RandallShanePhD

For Swift 5:

对于 Swift 5:

##代码##

回答by W?odzimierz Wo?niak

SWIFT 3:Check 3G & Wi-Fi connection

SWIFT 3:检查 3G 和 Wi-Fi 连接

##代码##