我一直在通过互联网搜索,以找到在iOS中检查互联网连接的最佳方法,该方法适用于IPv4和IPv6网络环境.我发现有很多可能的答案,但很难混淆哪一个适用.我需要做的是以下内容:
// Check for internet connection if (internetConnectionIsAvailable) { // make rest calls }else // show cached data }
我在互联网上找到了以下选项.
选项1:
使用apple Reachability类
有了Reachability,我可以检查互联网连接如下,这是短而直接的,并且不必等待任何响应.
- (BOOL)connected { Reachability *reachability = [Reachability reachabilityForInternetConnection]; NetworkStatus networkStatus = [reachability currentReachabilityStatus]; return !(networkStatus == NotReachable); } - (void)viewDidLoad { [super viewDidLoad]; if (![self connected]){ // Not connected }else{ // Connected } }
但是这里的互联网检查是在飞行前完成的,这违反了WWDC video所见的苹果工程师的建议.另外,如果你检查ReadMe.md,已经提到Reachability完全支持IPv6.但是如果在Reachability.m中检查了方法reachabilityForInternetConnection,则他们使用了sockaddr_in,但是没有使用sockaddr_in6,这是推荐用于IPv6网络的.所以我不知道它是否适用于IPv6网络.
选项2:使用Alamofire进行连接
>尝试按照stackoverflow answer之一进行连接.代码如下所示: –
Alamofire.request(.GET,"http://superrandomdomainnamethatisnotused.com/superrandompath").responseString { (request,response,stringData,error) in if let networkError = error { if (networkError.code == -1009) { println("No Internet \(error)") } } }
但尝试连接到某个主机,等待响应然后知道是否在线/离线并不是耗时的.
选项3:使用Tony Million的Reachability版本.但作者已经警告应用程序在使用时被拒绝.我可以使用此代码如下所示: –
// Checks if we have an internet connection or not - (void)testInternetConnection { internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"]; // Internet is reachable internetReachableFoo.reachableBlock = ^(Reachability*reach) { // Update the UI on the main thread dispatch_async(dispatch_get_main_queue(),^{ NSLog(@"There in internet connection"); }); }; // Internet is not reachable internetReachableFoo.unreachableBlock = ^(Reachability*reach) { // Update the UI on the main thread dispatch_async(dispatch_get_main_queue(),^{ NSLog(@"Someone broke the internet :("); }); }; [internetReachableFoo startNotifier]; }
但在这个选项中,我的问题是,这是通过连接http://google.com测试互联网的正确方法.这可以保证100%的结果吗?如果谷歌关闭怎么办?如果该应用在不允许使用google.com的国家/地区使用,结果是什么?
因此,如果这些选项是正确的方式,或者有更好的方法来检查互联网,保证100%的结果,并且在IPv4和IPv6网络中均可使用,那么我一直处于选择的选择中.任何人都可以建议我哪个选项更好或者我应该采取其他方法,有什么是更好的方法来实现这一目标.
非常感谢您的回复.
解决方法
对于Swift 3,Xcode 8 ……
func isInternetAvailable() -> 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) }