How to use reachability class to detect valid internet connection?

半城伤御伤魂 提交于 2019-11-26 10:28:40

问题


I\'m new to iOS development and am struggling to get the reachability.h class to work. Here is my code for view controller:

- (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.

I\'m using Reachability 2.2 and iOS 4.2.

Is there something obvious that I am doing wrong?


回答1:


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):

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).




回答2:


Here's how I do it. I have an instance variable that I set in my init method:

_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:

    NotReachable // No network
    ReachableViaWiFi // Reachable via Wifi
    ReachableViaWWAN // Reachable via cellular



回答3:


Update: Nov 4 2013

Using Reachability 3.0 version on iOS7

To build on top of @NR4TR and @codecaffeine's answers:

There are 5 ways to do this (not compiled :)

#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";



回答4:


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.

Add system.configuration.framewok, and also add Reachability.m and Reachability.h files in to your project. there after use methods like

+(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




回答5:


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



回答6:


Refer below code to check 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;



回答7:


The very simplest method (once you have added Reachability to your project):

Reachability *reachability = [Reachability reachabilityForInternetConnection];
if (reachability.isReachable) {
    NSLog(@"We have internet!");
} else {
    NSLog(@"No internet!");
}


来源:https://stackoverflow.com/questions/5195012/how-to-use-reachability-class-to-detect-valid-internet-connection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!