检查Swift中的网络状态

时间:2014-07-01 18:10:23

标签: swift

如何检查Swift中的网络状态?在Objective-C中, Reachability.h .m 文件可用。现在怎么办?如何查看我是在线还是离线?

7 个答案:

答案 0 :(得分:14)

如果您正在寻找Swift实施Apple的Reachability类,您可以看一下:

http://github.com/ashleymills/Reachability.swift

使用通知闭包,这是一个下降。

答案 1 :(得分:11)

你仍然可以在Swift中使用Reachability。对于如何将objective-c文件添加到桥接头here,Logan有一个很好的答案。设置桥接标头后,可以从Swift代码中调用Reachability方法。像这样的东西会起作用:

class func hasConnectivity() -> Bool {
    let reachability: Reachability = Reachability.reachabilityForInternetConnection()
    let networkStatus: Int = reachability.currentReachabilityStatus().value
    return networkStatus != 0
}

答案 2 :(得分:7)

我将提供最佳解决方案,希望它有所帮助。

import Foundation
import SystemConfiguration

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
            }

        }
        else
        {

            let alert = UIAlertView(title: "No Internet Connection", message: "Make sure your device is connected to the internet.", delegate: nil, cancelButtonTitle: "OK")
            alert.show()
        }

        return Status
    }
}

如何访问或致电其他课程:

 if Reachability.isConnectedToNetwork() == true {

// write your code

}

答案 3 :(得分:4)

首先将Reachability.swift文件添加到您可以从链接

下面获得的项目中

https://github.com/pavangandhi/TestProject/tree/master/TestProject/AppConstants

使用以下给定的代码测试应用程序是否与互联网连接:

//检查互联网连接,如果它返回YES意味着它连接互联网,Wifi和蜂窝数据

class func isConnectedToNetwork() -> Bool 
{
    let reachability = Reachability.reachabilityForInternetConnection()

    if reachability.isReachable() || reachability.isReachableViaWiFi() || reachability.isReachableViaWWAN()
    {
        return true
    }
    else
    {
        return false
    }
}

注意:在添加此代码之前,您需要将Reachability.swift文件添加到项目中。

答案 4 :(得分:3)

我已成功使用this article中的代码。虽然在发布我的应用程序后,我意识到google.com在中国被封锁,而且这个代码在Google被封锁的国家/地区存在缺陷。所以我调整它以检查第二个URL是否第一个失败。如果第二个成功,那么我将其保存为首选URL。

编辑虽然以下代码仍然有效,但在野外使用后我发现通过加载网址测试网络会导致用户连接到弱端时出现无法接受的延迟(非-4G)蜂窝数据连接。我现在使用上面@Ashley Mills建议的Reachability类。

public class Network {

class func isConnectedToNetwork() -> Bool{
    let defaults = NSUserDefaults.standardUserDefaults()

    var networkStatus:Bool = false
    let urlA = NSURL(string: "http://google.com/")
    let urlB = NSURL(string: "http://baidu.com/")

    let urlDict:[String:NSURL] = ["A":urlA!, "B":urlB!]

    var preference = "A"

    if let temp = defaults.stringForKey("preferredNetworkURL") {
        preference = temp //check the last successful URL or A by default
    } else {
        defaults.setObject(preference, forKey: "preferredNetworkURL")
    }

    networkStatus = Network.fetchURL(urlDict[preference]!, pref:preference)

    if networkStatus == false {
        //check the URL which hasn't been checked
        if preference == "A" {
            preference = "B"
        } else {
            preference = "A"
        }
        networkStatus = Network.fetchURL(urlDict[preference]!, pref:preference)
        println("NETWORK STATUS: \(networkStatus)")
        //if preference "B" returns true, then Baidu.com is available and user is likely in a country where Google is blocked
    }

    return networkStatus
}

class func fetchURL(url:NSURL, pref:String) -> Bool {
    println("URL PREFERENCE: \(pref)")
    let defaults = NSUserDefaults.standardUserDefaults()
    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 {
            defaults.setObject(pref, forKey: "preferredNetworkURL") //remember the URL that succeeded and check it first next time
            return true
        } else {
            return false
        }
    } else {
        return false
    }
}

}

然后我需要检查网络连接的任何地方我打电话:

if Network.isConnectedToNetwork() == true {
    //perform network dependent actions
} else {
    var alert = UIAlertView(title: "Network Unavailable", message: "Please connect to the internet in order to proceed.", delegate: self, cancelButtonTitle: "OK")
    alert.show()
}

答案 5 :(得分:0)

检查(iOS)Xcode 7.2,Swift 2.0中的Internet连接可用性

  

这是检查网络可用性的简单方法。我设法将它翻译成Swift 2.0,这里是最终的代码。   现有的Apple Reachability类和其他第三方库似乎太复杂,无法转换为Swift。   这适用于3G和WiFi连接。   不要忘记将“SystemConfiguration.framework”添加到您的网络中。

 //Create new swift class file Reachability in your project.

 import SystemConfiguration


 public class InternetReachability {

  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($0)).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
  }

  }

// Check network connectivity from anywhere in project by using this code.

   if InternetReachability.isConnectedToNetwork() == true {
          print("Internet connection OK")
    } else {
         print("Internet connection FAILED")
  }

答案 6 :(得分:0)

@blwinters我重写了这段代码以使用闭包并使用最新版本的swift。

import AVFoundation
public class Network {

    class func isConnectedToNetwork(resultHandler: (isTrue: Bool) -> Void) {
        let defaults = NSUserDefaults.standardUserDefaults()

        let urlA = NSURL(string: "http://google.com/")
        let urlB = NSURL(string: "http://baidu.com/")

        let urlDict:[String:NSURL] = ["A":urlA!, "B":urlB!]

        var preference = "A"

        if let temp = defaults.stringForKey("preferredNetworkURL") {
            preference = temp //check the last successful URL or A by default
        } else {
            defaults.setObject(preference, forKey: "preferredNetworkURL")
        }

        Network.fetchURL(urlDict[preference]!, pref:preference) {
            isTrue in
            if isTrue == true {
                print("NETWORK STATUS: \(isTrue)")
                resultHandler(isTrue: isTrue)
            } else {
                //check the URL which hasn't been checked
                if preference == "A" {
                    preference = "B"
                } else {
                    preference = "A"
                }
                Network.fetchURL(urlDict[preference]!, pref:preference) {
                    isTrue in
                    print("NETWORK STATUS: \(isTrue)")
                    resultHandler(isTrue: isTrue)
                }
                //if preference "B" returns true, then Baidu.com is available and user is likely in a country where Google is blocked
            }
        }
    }

    class func fetchURL(url:NSURL, pref:String, resultHandler: (isTrue: Bool) -> Void) {
        print("URL PREFERENCE: \(pref)")
        let defaults = NSUserDefaults.standardUserDefaults()
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "HEAD"
        request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
        request.timeoutInterval = 10.0

        var returnBool = false
        let session = NSURLSession(configuration: .defaultSessionConfiguration())
        let dataTask = session.dataTaskWithRequest(request) {
            (let data, let response, let error) in
            if let httpResponse = response as? NSHTTPURLResponse {
                if httpResponse.statusCode == 200 {
                    defaults.setObject(pref, forKey: "preferredNetworkURL") //remember the URL that succeeded and check it first next time
                    returnBool = true
                    resultHandler(isTrue: returnBool)
                } else {
                    returnBool = false
                    resultHandler(isTrue: returnBool)
                }
            } else {
                returnBool = false
                resultHandler(isTrue: returnBool)
            }
        }
        dataTask.resume()
    }
}

然后你就这样使用它

    Network.isConnectedToNetwork(){
        isConnected in
        if isConnected == true {
            dispatch_async(dispatch_get_main_queue()) {
                    //perform network dependent actions
                    //can remove the dispatch async if non UI actions
            }
        } else {
            dispatch_async(dispatch_get_main_queue()) {
                let alertController = UIAlertController(title: "Network Unavailable", message: "Please connect to the internet in order to proceed.", preferredStyle: UIAlertControllerStyle.Alert)
                alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default,handler: nil))
                self.presentViewController(alertController, animated: true, completion: nil)
            }
        }
    }