检查在斯威夫特的互联网连接的可用性
有没有办法检查互联网连接是否可以使用Swift?
我知道有许多第三方库可以做到这一点,但都是用Objective-C编写的。 我正在寻找一个Swift的替代品。
正如评论中所提到的,虽然可以在Swift中使用Objective-C库,但我想要一个更纯粹的Swift解决scheme。 现有的Apple Reachability类和其他第三方库似乎太复杂了,我不能翻译成Swift。 我google了一些,我碰到这篇文章 ,显示了一个简单的方法来检查networking的可用性。 我着手把这个翻译成Swift。 我遇到了很多困难,但是感谢来自StackOverflow的Martin R ,我设法解决了这些问题,并最终在Swift中获得了可行的解决scheme。 这是代码。
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 } }
这适用于3G和WiFi连接。 我也通过一个实例将其上传到我的GitHub 。
对于Swift 3,Swift 4: Working in cellular and Wi - Fi
创build一个新的Swift(anything.swift)类并在项目的任何地方访问它
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 } /* 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) return ret } }
用法:(在你的项目中的任何地方)
if Reachability.isConnectedToNetwork() { print("Internet Connection Available!") } else { print("Internet Connection not Available!") }
我给你更好的方法…
您必须使用此代码创build一个类
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 } }
然后,您可以使用以下代码检查项目中的任何位置的Internet连接:
if Reachability.isConnectedToNetwork() == true { println("Internet connection OK") } else { println("Internet connection FAILED") }
好简单!
*这种方式是基于Vikram Pote答案!
对于Swift 3.1(iOS 10.1)
如果你想区分networkingtypes(即WiFi或WWAN):
您可以使用:
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 } }
以下是区分networkingtypes的整个Reachability-Class:
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) { $0.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 } } }
由于sendSynchronousRequest被弃用,我尝试了这个,但在响应完成之前调用了“返回状态”。
这个答案很好,虽然, 检查互联网连接与斯威夫特
这是我无论如何都试过的:
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 } }
SWIFT 3:检查WiFi和互联网连接:
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, { $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.contains(.reachable) let needsConnection = flags.contains(.connectionRequired) return (isReachable && !needsConnection) } }
用法:
if Reachability.isConnectedToNetwork() == true { print("Connected to the internet") // Do something } else { print("No internet connection") // Do something }
你也可以使用下面的答案。
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 } }) }
SWIFT 3:检查3G和Wi-Fi连接
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() }