检查互联网连接 (iOS 10)
Check internet connection (iOS 10)
对于 iOS 9 我正在使用 Reachability public class 检查设备是否已连接到互联网。我将 Swift 2 代码转换为 Swift 3,并且可达性不再起作用。谁能告诉我如何检查 iOS 10 上的互联网连接?谢谢!
这是代码片段:
open class Reachability {
class func isConnectedToNetwork() -> 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) {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer([=11=]))
}
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)
}
}
import Foundation
import SystemConfiguration
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) {
[=10=].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)
return (isReachable && !needsConnection)
}
这适用于 iOS 10
试试这个,对我有用
首先 将 系统配置 导入 到您的 class.
import SystemConfiguration
现在实现波纹管功能。
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) {
[=11=].withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
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)
}
SWIFT3.0:
这是非常简单的方法:
import SystemConfiguration
protocol Utilities {
}
extension NSObject:Utilities{
enum ReachabilityStatus {
case notReachable
case reachableViaWWAN
case reachableViaWiFi
}
var currentReachabilityStatus: ReachabilityStatus {
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, {
[=10=].withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, [=10=])
}
}) else {
return .notReachable
}
var flags: SCNetworkReachabilityFlags = []
if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
return .notReachable
}
if flags.contains(.reachable) == false {
// The target host is not reachable.
return .notReachable
}
else if flags.contains(.isWWAN) == true {
// WWAN connections are OK if the calling application is using the CFNetwork APIs.
return .reachableViaWWAN
}
else if flags.contains(.connectionRequired) == false {
// If the target host is reachable and no connection is required then we'll assume that you're on Wi-Fi...
return .reachableViaWiFi
}
else if (flags.contains(.connectionOnDemand) == true || flags.contains(.connectionOnTraffic) == true) && flags.contains(.interventionRequired) == false {
// The connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs and no [user] intervention is needed
return .reachableViaWiFi
}
else {
return .notReachable
}
}
}
然后您可以在项目的任何地方使用它,例如:
func viewDidLoad(){
print(currentReachabilityStatus != .notReachable) //true connected
}
您可以在 swift 3
中使用
import SystemConfiguration
class Connection {
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([=10=]))
}
var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return isReachable && !needsConnection
}
}
第 1 步:在您的项目中创建一个 swift 文件。我创建了 "ConnectionCheck.swift"
第 2 步:将此代码添加到您的 "ConnectionCheck.swift" 文件和 "import SystemConfiguration" 文件到您的 "ConnectionCheck.swift" 和 "ViewController.swift"
import Foundation
import SystemConfiguration
public class ConnectionCheck {
class 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, {
[=10=].withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, [=10=])
}
}) 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)
}
}
第 3 步:现在 "ViewController.swift" 使用此代码检查网络可达性
if ConnectionCheck.isConnectedToNetwork() {
print("Connected")
}
else{
print("disConnected")
}
这里是Swift 3通过回调函数的解决方案,isConnectedToNetwork()
取自上面Yasin Ugurlu的解决方案。
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()
}
此代码会对您有所帮助。它在 Swift 4 和 Xcode 9
对我有用
转到https://github.com/ashleymills/Reachability.swift/tree/master/Reachability
并将 Reachability.swift 文件复制到您的项目
Vasil Nunev 清楚地解释了这个 Reachability
https://www.youtube.com/watch?v=wDZmz9IsB-8
class ViewController: UIViewController {
let reachability = Reachability();
override func viewDidLoad() {
super.viewDidLoad()
reachability?.whenReachable = { _ in
DispatchQueue.main.async {
self.view.backgroundColor = UIColor.green
}
}
reachability?.whenUnreachable = { _ in
DispatchQueue.main.async {
self.view.backgroundColor = UIColor.red
}
}
NotificationCenter.default.addObserver(self, selector: #selector(internetChanged), name: Notification.Name.reachabilityChanged , object: reachability)
do{
try reachability?.startNotifier()
}catch{
print("Could not start notifier:\(error)")
}
}
@objc func internetChanged(note:Notification) {
let reachability = note.object as! Reachability
if reachability.connection != .none {
if reachability.connection == .wifi{
DispatchQueue.main.async {
self.view.backgroundColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
}
}else if reachability.connection == .cellular{
DispatchQueue.main.async {
self.view.backgroundColor = #colorLiteral(red: 0.3647058904, green: 0.06666667014, blue: 0.9686274529, alpha: 1)
}
}
}else{
DispatchQueue.main.async {
self.view.backgroundColor = #colorLiteral(red: 0.7450980544, green: 0.1568627506, blue: 0.07450980693, alpha: 1)
}
}
}
}
Swift 4 / Xcode 10:
我会结合@Pavle Mijatovic 和@Krutagn Patel(感谢)的解决方案中的两个函数(稍作更改)来回答@Lance Samaria 问题。 :)
我几乎检查了所有的可能性。 (代码可以增强,但效果很好)
有一个 class 如下:
import Foundation
import SystemConfiguration
public class ConnectionCheck {
class 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, {
[=10=].withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, [=10=])
}
}) 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)
}
class func isInternetAvailable(webSiteToPing: String?, completionHandler: @escaping (_ b: 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()
}
}
在需要检查互联网连接的地方使用下面的代码:例如,在 appDelegate -> applicationDidBecomeActive 函数中。
说明:每当调用 completionHandler 函数(上面)时,结果(true 或 false)作为 b
传递给下面的代码。因此,如果 b 为真,则说明您已连接到互联网。
let web : String? = "https://www.google.com"
ConnectionCheck.isInternetAvailable(webSiteToPing: web) { (b) in
print(b)
if b {
print("connected") // or do something here
} else {
print("disconnected") // or do something here
}
}
1) 在您的项目中创建一个新的 Swift 文件,将其命名为“Reachability.swift”。
2) 将以下代码剪切并粘贴到其中以创建您的 class。
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([=10=]))
}
var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
return false
}
let isReachable = flags == .Reachable
let needsConnection = flags == .ConnectionRequired
return isReachable && !needsConnection
}
}
3) 您可以使用此代码在项目的任何位置检查互联网连接:
if Reachability.isConnectedToNetwork() == true {
println("Internet connection OK")
} else {
println("Internet connection FAILED")
}
4)如果用户未连接到 Internet,您可能希望向他们显示一个警告对话框以通知他们。
if Reachability.isConnectedToNetwork() == true {
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()
}
Swift 4/Xcode 9+(制作Reachability.swift文件):
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) {
[=10=].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
}
}
用法:
if Reachability.isConnectedToNetwork() {
// connected, do something
}
在您的项目中创建一个 Swift 文件,将其命名为:Reachability.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([=10=]))
}
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() == true {
println("Internet connection OK")
} else {
println("Internet connection FAILED")
}
Swift 4.0 的另一个解决方案。不是 IUO 的忠实粉丝,而是使用守卫
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, {
[=10=].withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, [=10=])
}
}) else {
return false
}
var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == false {
return false
}
let isReachable = flags == .reachable
let needsConnection = flags == .connectionRequired
return isReachable && !needsConnection
}
对于 iOS 9 我正在使用 Reachability public class 检查设备是否已连接到互联网。我将 Swift 2 代码转换为 Swift 3,并且可达性不再起作用。谁能告诉我如何检查 iOS 10 上的互联网连接?谢谢! 这是代码片段:
open class Reachability {
class func isConnectedToNetwork() -> 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) {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer([=11=]))
}
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)
}
}
import Foundation
import SystemConfiguration
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) {
[=10=].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)
return (isReachable && !needsConnection)
}
这适用于 iOS 10
试试这个,对我有用 首先 将 系统配置 导入 到您的 class.
import SystemConfiguration
现在实现波纹管功能。
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) {
[=11=].withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
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)
}
SWIFT3.0: 这是非常简单的方法:
import SystemConfiguration
protocol Utilities {
}
extension NSObject:Utilities{
enum ReachabilityStatus {
case notReachable
case reachableViaWWAN
case reachableViaWiFi
}
var currentReachabilityStatus: ReachabilityStatus {
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, {
[=10=].withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, [=10=])
}
}) else {
return .notReachable
}
var flags: SCNetworkReachabilityFlags = []
if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
return .notReachable
}
if flags.contains(.reachable) == false {
// The target host is not reachable.
return .notReachable
}
else if flags.contains(.isWWAN) == true {
// WWAN connections are OK if the calling application is using the CFNetwork APIs.
return .reachableViaWWAN
}
else if flags.contains(.connectionRequired) == false {
// If the target host is reachable and no connection is required then we'll assume that you're on Wi-Fi...
return .reachableViaWiFi
}
else if (flags.contains(.connectionOnDemand) == true || flags.contains(.connectionOnTraffic) == true) && flags.contains(.interventionRequired) == false {
// The connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs and no [user] intervention is needed
return .reachableViaWiFi
}
else {
return .notReachable
}
}
}
然后您可以在项目的任何地方使用它,例如:
func viewDidLoad(){
print(currentReachabilityStatus != .notReachable) //true connected
}
您可以在 swift 3
中使用import SystemConfiguration
class Connection {
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([=10=]))
}
var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return isReachable && !needsConnection
}
}
第 1 步:在您的项目中创建一个 swift 文件。我创建了 "ConnectionCheck.swift"
第 2 步:将此代码添加到您的 "ConnectionCheck.swift" 文件和 "import SystemConfiguration" 文件到您的 "ConnectionCheck.swift" 和 "ViewController.swift"
import Foundation
import SystemConfiguration
public class ConnectionCheck {
class 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, {
[=10=].withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, [=10=])
}
}) 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)
}
}
第 3 步:现在 "ViewController.swift" 使用此代码检查网络可达性
if ConnectionCheck.isConnectedToNetwork() {
print("Connected")
}
else{
print("disConnected")
}
这里是Swift 3通过回调函数的解决方案,isConnectedToNetwork()
取自上面Yasin Ugurlu的解决方案。
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()
}
此代码会对您有所帮助。它在 Swift 4 和 Xcode 9
对我有用转到https://github.com/ashleymills/Reachability.swift/tree/master/Reachability 并将 Reachability.swift 文件复制到您的项目
Vasil Nunev 清楚地解释了这个 Reachability https://www.youtube.com/watch?v=wDZmz9IsB-8
class ViewController: UIViewController {
let reachability = Reachability();
override func viewDidLoad() {
super.viewDidLoad()
reachability?.whenReachable = { _ in
DispatchQueue.main.async {
self.view.backgroundColor = UIColor.green
}
}
reachability?.whenUnreachable = { _ in
DispatchQueue.main.async {
self.view.backgroundColor = UIColor.red
}
}
NotificationCenter.default.addObserver(self, selector: #selector(internetChanged), name: Notification.Name.reachabilityChanged , object: reachability)
do{
try reachability?.startNotifier()
}catch{
print("Could not start notifier:\(error)")
}
}
@objc func internetChanged(note:Notification) {
let reachability = note.object as! Reachability
if reachability.connection != .none {
if reachability.connection == .wifi{
DispatchQueue.main.async {
self.view.backgroundColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
}
}else if reachability.connection == .cellular{
DispatchQueue.main.async {
self.view.backgroundColor = #colorLiteral(red: 0.3647058904, green: 0.06666667014, blue: 0.9686274529, alpha: 1)
}
}
}else{
DispatchQueue.main.async {
self.view.backgroundColor = #colorLiteral(red: 0.7450980544, green: 0.1568627506, blue: 0.07450980693, alpha: 1)
}
}
}
}
Swift 4 / Xcode 10:
我会结合@Pavle Mijatovic 和@Krutagn Patel(感谢)的解决方案中的两个函数(稍作更改)来回答@Lance Samaria 问题。 :)
我几乎检查了所有的可能性。 (代码可以增强,但效果很好)
有一个 class 如下:
import Foundation
import SystemConfiguration
public class ConnectionCheck {
class 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, {
[=10=].withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, [=10=])
}
}) 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)
}
class func isInternetAvailable(webSiteToPing: String?, completionHandler: @escaping (_ b: 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()
}
}
在需要检查互联网连接的地方使用下面的代码:例如,在 appDelegate -> applicationDidBecomeActive 函数中。
说明:每当调用 completionHandler 函数(上面)时,结果(true 或 false)作为 b
传递给下面的代码。因此,如果 b 为真,则说明您已连接到互联网。
let web : String? = "https://www.google.com"
ConnectionCheck.isInternetAvailable(webSiteToPing: web) { (b) in
print(b)
if b {
print("connected") // or do something here
} else {
print("disconnected") // or do something here
}
}
1) 在您的项目中创建一个新的 Swift 文件,将其命名为“Reachability.swift”。
2) 将以下代码剪切并粘贴到其中以创建您的 class。
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([=10=]))
}
var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
return false
}
let isReachable = flags == .Reachable
let needsConnection = flags == .ConnectionRequired
return isReachable && !needsConnection
}
}
3) 您可以使用此代码在项目的任何位置检查互联网连接:
if Reachability.isConnectedToNetwork() == true {
println("Internet connection OK")
} else {
println("Internet connection FAILED")
}
4)如果用户未连接到 Internet,您可能希望向他们显示一个警告对话框以通知他们。
if Reachability.isConnectedToNetwork() == true {
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()
}
Swift 4/Xcode 9+(制作Reachability.swift文件):
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) {
[=10=].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
}
}
用法:
if Reachability.isConnectedToNetwork() {
// connected, do something
}
在您的项目中创建一个 Swift 文件,将其命名为:Reachability.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([=10=])) } 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() == true {
println("Internet connection OK")
} else {
println("Internet connection FAILED")
}
Swift 4.0 的另一个解决方案。不是 IUO 的忠实粉丝,而是使用守卫
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, {
[=10=].withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, [=10=])
}
}) else {
return false
}
var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == false {
return false
}
let isReachable = flags == .reachable
let needsConnection = flags == .connectionRequired
return isReachable && !needsConnection
}