ios 如何使用可达性类来检测有效的互联网连接?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5195012/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use reachability class to detect valid internet connection?
提问by Camsoft
I'm new to iOS development and am struggling to get the reachability.h class to work. Here is my code for view controller:
我是 iOS 开发的新手,正在努力让reachability.h 类工作。这里是我的视图控制器代码:
- (void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(checkNetworkStatus:)
name:kReachabilityChangedNotification
object:nil];
internetReachable = [Reachability reachabilityForInternetConnection];
[internetReachable startNotifier];
}
- (void)checkNetworkStatus:(NSNotification *)notice {
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
NSLog(@"Network status: %i", internetStatus);
}
It looks ok but nothing is appearing in the xcode console when running the app and switching to that view.
看起来没问题,但在运行应用程序并切换到该视图时,xcode 控制台中没有出现任何内容。
I'm using Reachability 2.2 and iOS 4.2.
我使用的是可达性 2.2 和 iOS 4.2。
Is there something obvious that I am doing wrong?
有什么明显的我做错了吗?
回答by knuku
EDITED:If you want to check reachability before some code execution you should just use
编辑:如果你想在一些代码执行之前检查可达性,你应该使用
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus internetStatus = [reachability currentReachabilityStatus];
if (internetStatus != NotReachable) {
//my web-dependent code
}
else {
//there-is-no-connection warning
}
You can also add a reachability observer somewhere (i.e. in viewDidLoad
):
您还可以在某处(即在viewDidLoad
)中添加可达性观察器:
Reachability *reachabilityInfo;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(myReachabilityDidChangedMethod)
name:kReachabilityChangedNotification
object:reachabilityInfo];
Don't forget to call [[NSNotificationCenter defaultCenter] removeObserver:self];
when you no longer need reachability detection (i.e. in dealloc
method).
[[NSNotificationCenter defaultCenter] removeObserver:self];
当您不再需要可达性检测(即在dealloc
方法中)时,不要忘记调用。
回答by codecaffeine
Here's how I do it. I have an instance variable that I set in my init method:
这是我如何做到的。我在 init 方法中设置了一个实例变量:
_reachability = [[APReachability reachabilityForInternetConnection] retain];
and when I need to query the network status, I do:
当我需要查询网络状态时,我会这样做:
NetworkStatus networkStatus = [_reachability currentReachabilityStatus];
if (networkStatus != NotReachable) {
// Network related code
}
else {
// No network code
}
If you care about wifi, etc, network status can be:
如果您关心 wifi 等,网络状态可以是:
NotReachable // No network
ReachableViaWiFi // Reachable via Wifi
ReachableViaWWAN // Reachable via cellular
回答by Dickey Singh
Update: Nov 4 2013
更新:2013 年 11 月 4 日
Using Reachability 3.0 version on iOS7
在 iOS7 上使用 Reachability 3.0 版本
To build on top of @NR4TR and @codecaffeine's answers:
建立在@NR4TR 和@codecaffeine 的答案之上:
There are 5 ways to do this (not compiled :)
有 5 种方法可以做到这一点(未编译 :)
#include <ifaddrs.h>
#include <arpa/inet.h>
//1 - Is www.apple.com reachable?
Reachability *rHostName = [Reachability reachabilityWithHostName:@"www.apple.com"];
NetworkStatus s1 = [rHostName currentReachabilityStatus];
//2 - Is local wifi router or access point reachable?
Reachability *rLocalWiFi = [Reachability reachabilityForLocalWiFi];
NetworkStatus s2 = [rLocalWiFi currentReachabilityStatus];
//3 - Is my access point connected to a router and the router connected to the internet?
Reachability *rConnection = [Reachability reachabilityForInternetConnection];
NetworkStatus s3 = [rConnection currentReachabilityStatus];
//4 IPv4 standard addresses checking instead of host to avoid dns lookup step
struct sockaddr_in saIPv4;
inet_pton(AF_INET, "74.125.239.51", &(saIPv4.sin_addr));
saIPv4.sin_len = sizeof(saIPv4);
saIPv4.sin_family = AF_INET;
Reachability *rIPv4 = [Reachability reachabilityWithAddress:&saIPv4];
NetworkStatus s4 = [rIPv4 currentReachabilityStatus];
//5 IPv6 addresses checking instead of host to avoid dns lookup step
struct sockaddr_in saIPv6;
inet_pton(AF_INET, "2607:f8b0:4010:801::1014", &(saIPv6.sin_addr));
saIPv6.sin_len = sizeof(saIPv6);
saIPv6.sin_family = AF_INET;
Reachability *rIPv6 = [Reachability reachabilityWithAddress:&saIPv6];
NetworkStatus s5 = [rIPv6 currentReachabilityStatus];
Handling status is same
处理状态相同
if (ReachableViaWiFi == s1)
return @"WiFi"; //@"WLAN"
if (ReachableViaWWAN == s1)
return @"Cellular"; //@"WWAN"
return @"None";
回答by Sowjanya lankisetty
Follow this link, it has very useful source code and steps https://github.com/tonymillion/Reachability. This provides you info about how can you use different methods in Reachability to play around.
按照这个链接,它有非常有用的源代码和步骤 https://github.com/tonymillion/Reachability。这为您提供了有关如何在 Reachability 中使用不同方法进行操作的信息。
Add system.configuration.framewok, and also add Reachability.m and Reachability.h files in to your project. there after use methods like
添加 system.configuration.framewok,并将 Reachability.m 和 Reachability.h 文件添加到您的项目中。使用方法后有
+(instancetype)reachabilityWithHostName:(NSString*)hostname;
+(instancetype)reachabilityForInternetConnection;
+(instancetype)reachabilityWithAddress:(void *)hostAddress;
+(instancetype)reachabilityForLocalWiFi;
Example snippet:
示例片段:
- (void)CheckConnection
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
Reachability * reach = [Reachability reachabilityWithHostname:@"www.google.com"];
reach.reachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
_blockLabel.stringValue = @"Block Says Reachable";
});
};
reach.unreachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
_blockLabel.stringValue = @"Block Says Unreachable";
});
};
[reach startNotifier];
}
Hope this helps
希望这可以帮助
回答by Inti
The very simplest method (once you have added Reachabilityto your project):
最简单的方法(一旦您将Reachability添加到您的项目中):
Reachability *reachability = [Reachability reachabilityForInternetConnection];
if (reachability.isReachable) {
NSLog(@"We have internet!");
} else {
NSLog(@"No internet!");
}
回答by mahesh chowdary
just Import Reachability classes and after that
只需导入可达性类,然后
-(BOOL) connectedToNetwork
{
const char *host_name = "www.google.com";
BOOL _isDataSourceAvailable = NO;
Boolean success;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL,host_name);
SCNetworkReachabilityFlags flags;
success = SCNetworkReachabilityGetFlags(reachability, &flags);
_isDataSourceAvailable = success &&
(flags & kSCNetworkFlagsReachable) &&
!(flags & kSCNetworkFlagsConnectionRequired);
CFRelease(reachability);
return _isDataSourceAvailable;
}
回答by Kiran K
Refer below code to check Internet Connectivity
:
请参阅以下代码进行检查Internet Connectivity
:
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr*)&zeroAddress);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags) {
return 0;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
NSURL *testURL = [NSURL URLWithString:@"http://www.google.com/"];
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *connectiondata = [NSURLConnection sendSynchronousRequest:testRequest
returningResponse:&response
BOOL connection=NO;
if ([connectiondata length] > 0 &&
error == nil){
NSLog(@"Connection present” );
connection=YES;
} else {
NSLog(@"No Connection" );
connection=NO;
}
return ((isReachable && !needsConnection) || nonWiFi) ? (connection ? YES : NO) : NO;