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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:07:03  来源:igfitidea点击:

How to use reachability class to detect valid internet connection?

objective-ciosios4reachability

提问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 deallocmethod).

[[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;