15

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?

Camsoft
  • 11,718
  • 19
  • 83
  • 120

7 Answers7

56

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

knuku
  • 6,082
  • 1
  • 35
  • 43
  • Thanks for this but I get an error saying -isReachable is not found. Is your example for an older version of reachability by any chance? – Camsoft Mar 04 '11 at 15:41
  • This likely causes big trouble. How about VPN connections on Demand, and other problematic things? – Proud Member May 29 '12 at 16:05
  • Of course it is not must, but i can't imagine good web service related app without any usage of reachability – knuku Jan 25 '13 at 12:21
6

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
codecaffeine
  • 904
  • 8
  • 13
4

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";
Dickey Singh
  • 713
  • 1
  • 8
  • 16
3

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

0

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;
}
Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
mahesh chowdary
  • 432
  • 5
  • 13
0

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;
Mihriban Minaz
  • 3,043
  • 2
  • 32
  • 52
Kiran K
  • 919
  • 10
  • 17
0

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!");
}
Inti
  • 3,443
  • 1
  • 29
  • 34