检查Swift中的互联网连接是否可用。

13

是否有苹果框架束来检测是否存在互联网连接?当前,我的应用程序在没有互联网连接的情况下尝试定位用户位置时会崩溃。

/*inside locationManager didUpdateLocations method*/
var currentLocation:CLLocation? = locations[0] as? CLLocation
geocoder = CLGeocoder()
//Crashes on line below when there isn't an internet connection
//Need to add function to check if internet connection is live 
//Before running reverseGeocodeLocation
geocoder.reverseGeocodeLocation (currentLocation,handleGeocode)

我对Swift和iOS编程还有点陌生,抱歉。


2
由于Swift可以向Objective-C对象发送消息,因此另一个问题的答案也适用于这里。如果您在将该答案集成到项目中遇到困难,请随时创建一个新问题,寻求帮助。 - rob mayoff
Rob,我正在寻找一个快速的解决方案而不是Objective-C的解决方案...在我看来,我希望我的所有代码都是用Swift而不是Objective-C编写的,这样更容易在一种语言中维护。我相信长期来看,所有的代码都必须被“移植”到Swift上。我想我将不得不用Swift重写Reachability类来实现这个目标? - PHPDave
4
也许你可以用Swift重新编写它。由于它是建立在需要注册回调函数的C框架(SystemConfiguration)之上,所以需要具备超出初学者水平的Swift知识。 - rob mayoff
1
@PHPDave Cocoa Touch API是用ObjC编写的,它在很长一段时间内都不会消失。我喜欢Swift,如果你学习ObjC,你会更擅长它。 - Woodstock
当程序崩溃时,您实际收到的错误是什么? - James Frost
显示剩余2条评论
3个回答

22

虽然它不是一种成熟的网络检查库,但我找到了这个简单的方法来检查网络是否可用。我已经成功将其转换为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(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) ? true : false
    }

}

它适用于3G和WiFi连接。我还将其上传到我的Github上,并提供了一个可行的示例。如果你正在寻找一种在Swift中纯粹检查网络可用性的简单方法,你可以使用它。


3
了解,这也适用于OS X操作系统。 - davecom
如果我的3G开启了,但我没有数据套餐,它会返回真吗? - NaveedUlHassan5

4

使用Babatunde的代码示例,这里是适用于Swift 2.0和错误处理的更新版本: 编辑:对于iOS 9,Google的URL也已更改为HTTPS。 编辑2:原始文章:http://www.brianjcoleman.com/tutorial-check-for-internet-connection-in-swift/

import Foundation
import SystemConfiguration

public class Reachability {

    // Check if internet connection is available

    class func isConnectedToNetwork() -> Bool {

        var status:Bool = false

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

        var response:NSURLResponse?

        do {
            let _ = try NSURLConnection.sendSynchronousRequest(request, returningResponse: &response) as NSData?
        }
        catch let error as NSError {
            print(error.localizedDescription)
        }

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

1
由于Reachability尚未完全移植到Swift,您可以使用下面的示例代码检查Internet连接:
public class Reachability {
/**
 * Check if internet connection is available
 */
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
  }
}

请见下面函数的示例用法:
// Check if internet is available before proceeding further
    if Reachability.isConnectedToNetwork() {
        // Go ahead and fetch your data from the internet
        // ...
    } else {
        println("Internet connection not available")

        var alert = UIAlertView(title: "No Internet connection", message: "Please ensure you are connected to the Internet", delegate: nil, cancelButtonTitle: "OK")
        alert.show()
    }

为了使用上述解决方案,您必须在info.plist文件中的NSAppTransportSecurity字典下将“NSAllowsArbitraryLoads”键设置为YES。否则,代码将无法正常工作。 - Sheetal Shinde

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接