当我试着在我的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'接受提供的参数
虽然它可能不能直接确定手机是否连接到网络,但最简单的解决方案是“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多个服务器,并返回它们中的任何一个是否可达。或者让别人专门为这个目的设置一个专用服务器。
iOS12 Swift 4和Swift 5
如果你只是想检查连接,你的最低目标是iOS12,那么你可以使用NWPathMonitor
import Network
它需要一些属性的设置。
let internetMonitor = NWPathMonitor()
let internetQueue = DispatchQueue(label: "InternetMonitor")
private var hasConnectionPath = false
我创建了一个函数来启动它。你可以在viewdidload或其他地方做这个。我派了个保镖,你想怎么打就怎么打。
func startInternetTracking() {
// only fires once
guard internetMonitor.pathUpdateHandler == nil else {
return
}
internetMonitor.pathUpdateHandler = { update in
if update.status == .satisfied {
print("Internet connection on.")
self.hasConnectionPath = true
} else {
print("no internet connection.")
self.hasConnectionPath = false
}
}
internetMonitor.start(queue: internetQueue)
}
/// will tell you if the device has an Internet connection
/// - Returns: true if there is some kind of connection
func hasInternet() -> Bool {
return hasConnectionPath
}
现在只需调用helper函数hasInternet()来查看是否有。它实时更新。请参阅Apple文档中的NWPathMonitor。它有更多的功能,如取消(),如果你需要停止跟踪连接,你正在寻找的互联网类型等。
https://developer.apple.com/documentation/network/nwpathmonitor
虽然没有直接回答你的问题,但我想提一下苹果公司最近有这样一个谈话:
https://developer.apple.com/videos/play/wwdc2018/714/
大约在9点55分,他谈到了做你正在问的事情:
检查连接
如果连接->做点什么
如果没有连接->执行其他操作(等待?重试?)
然而,这有一些陷阱:
如果在第二步中,它说它有连接,但0.5秒后他就没有了呢?
如果用户在代理的后面呢
最后但并非最不重要的是,如果这里的一些答案不能确定连通性呢?(我敢肯定,如果你快速切换你的连接,去wi-fi,然后关掉它(只是让它变得复杂),它几乎永远不能正确地判断我是否获得了连接)。
视频中说:“没有办法保证未来的行动是否会成功。”
以下是苹果公司的一些最佳实践:
设置waitsForConnectivity为true (https://developer.apple.com/documentation/foundation/urlsessionconfiguration/2908812-waitsforconnectivity)
响应委托方法taskIsWaitingForConnectivity (https://developer.apple.com/documentation/foundation/urlsessiontaskdelegate/2908819-urlsession)。这是苹果推荐的检查连接的方法,正如33:25的视频中提到的那样。
根据谈话,不应该有任何理由预先检查你是否有互联网连接,因为在你向服务器发送请求时,它可能并不准确。