当我试着在我的iPhone上检查网络连接时,我得到了一堆错误。有人能帮我解决这个问题吗?

代码:

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
}

}

代码的错误:

如果它是不可读的,错误1说:

'Int'不能转换为'SCNetworkReachabilityFlags'

错误2和3:

找不到一个超载的'init'接受提供的参数


当前回答

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

用法:

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

或者只是使用这个框架更多的实用程序:链接

其他回答

在项目中创建一个新的Swift文件,命名为Reachability.swift。将以下代码剪切并粘贴到其中以创建您的类。

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

    }
}

你可以使用下面的代码检查项目中的任何地方的互联网连接:

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

如果用户没有连接到互联网,您可能希望向他们显示一个警告对话框来通知他们。

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

解释:

我们正在制作一个可重用的公共类和方法,可以在项目的任何地方使用,以检查互联网连接。我们需要添加基础和系统配置框架。

在公共类Reachability中,方法isConnectedToNetwork() -> Bool{}将返回一个关于互联网连接的Bool值。我们使用if循环对case执行所需的操作。我希望这足够了。干杯!

虽然它可能不能直接确定手机是否连接到网络,但最简单的解决方案是“ping”谷歌或其他服务器(除非手机连接到网络,否则这是不可能的):

private var urlSession:URLSession = {
    var newConfiguration:URLSessionConfiguration = .default
    newConfiguration.waitsForConnectivity = false
    newConfiguration.allowsCellularAccess = true
    return URLSession(configuration: newConfiguration)
}()

public func canReachGoogle() -> Bool
{
    let url = URL(string: "https://8.8.8.8")
    let semaphore = DispatchSemaphore(value: 0)
    var success = false
    let task = urlSession.dataTask(with: url!)
    { data, response, error in
        if error != nil
        {
            success = false
        }
        else
        {
            success = true
        }
        semaphore.signal()
    }

    task.resume()
    semaphore.wait()

    return success
}

如果您担心服务器可能宕机或阻塞您的IP,您总是可以以类似的方式ping多个服务器,并返回它们中的任何一个是否可达。或者让别人专门为这个目的设置一个专用服务器。

Swift 5.5, iOS 12+,没有更多的第三方库。

请检查这个要点https://gist.github.com/dimohamdy/5166ba6c88f6954fa6b23bc9f28cbe12

使用

 startNetworkReachabilityObserver()
 
  if Reachability.shared.isConnected {
       print("no internet connection")   
  }

Code

import Network
import Foundation

class Reachability {

    static var shared = Reachability()
    lazy private var monitor = NWPathMonitor()

    var isConnected: Bool {
        return monitor.currentPath.status == .satisfied
    }

    func startNetworkReachabilityObserver() {
        monitor.pathUpdateHandler = { path in
            if path.status == .satisfied {
                NotificationCenter.default.post(name: Notifications.Reachability.connected.name, object: nil)
            } else if path.status == .unsatisfied {
                NotificationCenter.default.post(name: Notifications.Reachability.notConnected.name, object: nil)
            }
        }
        let queue = DispatchQueue.global(qos: .background)
        monitor.start(queue: queue)
    }
}

There is no real way to do this, even APIs that do this will try to connect to a particular service and tell you if it succeed after previously failing, the best approach is to just try to connect to your service and handle the error appropriately, if you want some service that will notify you when you become connected, all that will happens is that it periodically calls to a fixed service until it gets a response and then let you know that it succeed, what if the problem is not the internet itself but the specific service you are trying to connect to.

最好的方法是在你的连接方法中设计处理这个问题的方法,你可以在给定的时间内触发重试,这取决于你的错误,也许是失败的数量,你可以返回一个错误,你可以用它来显示一个错误消息,给用户一个重试的可能性,也许是尝试几次,然后返回和错误的组合。

另一个类似的问题是发送你已经发送但还没有得到响应的消息,最好还是写你的应用程序来处理这个,忽略请求,直到它等待的请求返回,如果请求不同,取消等待请求,等等

这些东西可以以非常通用的方式编写,所以它们可以用于应用程序的许多不同方面,甚至不同的项目。

对于swift 3,我不能只使用RAJAMOHAN-S解决方案的可达性,因为如果有WiFi但没有互联网,它会返回“true”。因此,我通过URLSession类和完成处理程序实现了第二次验证。

这是全班同学。

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

你可以这样称呼它,例如:

Reachability.isInternetAvailable(webSiteToPing: nil) { (isInternetAvailable) in
  guard isInternetAvailable else {
    // Inform user for example
    return
  }

  // Do some action if there is Internet
}