I would like to check to see if I have an Internet connection on iOS using the Cocoa Touch libraries or on OSX using the Cocoa libraries.

I came up with a way to do this using an NSURL. The way I did it seems a bit unreliable (because even Google could one day be down and relying on a third party seems bad), and while I could check to see for a response from some other websites if Google didn't respond, it does seem wasteful and an unnecessary overhead on my application.

- (BOOL) connectedToInternet
{
    NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];
    return ( URLString != NULL ) ? YES : NO;
}

Is what I have done bad? (Not to mention stringWithContentsOfURL is deprecated in iOS 3.0 and OSX 10.4) and if so, what is a better way to accomplish this?

upvote
  flag
You could replace the last line with: return (id)URLString; (Omitting the cast will also work, but might give you a compiler warning.) – Felixyz
8 upvote
  flag
Rather return (BOOL)URLString;, or even better, return !!URLString or return URLString != nil – user529758
3 upvote
  flag
I don't know what your use case is, but if you can it's preferable to try the request and handle any errors such as a lack of connection that arise. If you can't do this, then there's plenty of good advice here in this case. – SK9
2 upvote
  flag
Your solution is clever, and I prefer it. You can also use NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://twitter.com/getibox"] encoding:NSUTF8StringEncoding error:nil]; To get rid of the annoying warning. – Abdelrahman Eid
4 upvote
  flag
try using Reachability class from the below link, it will work for you github.com/tonymillion/Reachability – Dhaval Nena
3 upvote
  flag
For those recently finding this answer: //allinonescript.com/a/8813279 – afollestad
upvote
  flag
Or try this singleton class so you can set a timeout to avoid hangs in 100% packet loss scenarios. github.com/fareast555/TFInternetChecker – Mike Critchley
upvote
  flag
The fastest and easiest way to check connection - //allinonescript.com/a/8813279/5790492 – Nik Kov

36 Answers 11

Apple provides a sample app which does exactly this:

Reachability

5 upvote
  flag
You should note that the Reachability sample only detects which interfaces are active, but not which ones have a valid connection to the internet. Applications should gracefully handle failure even when Reachability reports that everything is ready to go. – rpetrich
upvote
  flag
Happily the situation is a lot better in 3.0, as the system will present a login page for users behind a locked down WiFi where you have to login to use... you use to have to check for the redirect manually (and you still do if developing 2.2.1 apps) – Kendall Helmstetter Gelner

Apple supplies sample code to check for different types of network availability. Alternatively there is an example in the iPhone developers cookbook.

Note: Please see @KHG's comment on this answer regarding the use of Apple's reachability code.

upvote
  flag
Thanks. I discovered that the Xcode documentation in 3.0 also contains the source code, found by searching for "reachability" in the documentation. – Brock Woolf
6 upvote
  flag
Note that the new revision (09-08-09) of the Reachability sample code from Apple is asynchronous. – Daniel Hepper

I've used the code in this discussion, and it seems to work fine (read the whole thread!).

I haven't tested it exhaustively with every conceivable kind of connection (like ad hoc Wi-Fi).

upvote
  flag
this code is not totally good because it just checks to see if you have wifi connection with a router, not if the web can be reached. You can have wifi working and continue enable to reach the web. – SpaceDog
upvote
  flag
And this is exactly what I wanted. Thanks Felixyz – ShayanK

This used to be the correct answer, but it is now outdated as you should subscribe to notifications for reachability instead. This method checks synchronously:


You can use Apple's Reachability class. It will also allow you to check if Wi-Fi is enabled:

Reachability* reachability = [Reachability sharedReachability];
[reachability setHostName:@"www.example.com"];    // Set your host name here
NetworkStatus remoteHostStatus = [reachability remoteHostStatus];

if (remoteHostStatus == NotReachable) { }
else if (remoteHostStatus == ReachableViaWiFiNetwork) { }
else if (remoteHostStatus == ReachableViaCarrierDataNetwork) { }

The Reachability class is not shipped with the SDK, but rather a part of this Apple sample application. Just download it, and copy Reachability.h/m to your project. Also, you have to add the SystemConfiguration framework to your project.

6 upvote
  flag
See my comment above about not using Reachability like that. Use it in asynchronous mode and subscribe to the notifications it sends - don't. – Kendall Helmstetter Gelner
upvote
  flag
This code is a good starting point for things that you need to set before you can use the delegate methods for the reachability class. – Brock Woolf

Only the Reachability class has been updated. You can now use:

Reachability* reachability = [Reachability reachabilityWithHostName:@"www.apple.com"];
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

if (remoteHostStatus == NotReachable) { NSLog(@"not reachable");}
else if (remoteHostStatus == ReachableViaWWAN) { NSLog(@"reachable via wwan");}
else if (remoteHostStatus == ReachableViaWiFi) { NSLog(@"reachable via wifi");}
1 upvote
  flag
Unless something changed since 4.0 was released, that code is not asynchronous and you are guaranteed to see it show up in Crash Reports - happened to me before. – bpapa
1 upvote
  flag
I agree with bpapa. It's not a good idea to use synchronous code. Thanks for the info though – Brock Woolf
up vote 1194 down vote accepted

METHOD 1: Use a simple (ARC and GCD compatible) class to do it

1) Add SystemConfiguration framework to the project but don't worry about including it anywhere

2) Add Tony Million's version of Reachability.h and Reachability.m to the project (found here: https://github.com/tonymillion/Reachability)

3) Update the interface section

#import "Reachability.h"

// Add this to the interface in the .m file of your view controller
@interface MyViewController ()
{
    Reachability *internetReachableFoo;
}
@end

4) Then implement this method in the .m file of your view controller which you can call

// 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(@"Yayyy, we have the interwebs!");
        });
    };

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

METHOD 2: Do it yourself the old way using Apple's outdated Reachability class

1) Add SystemConfiguration framework to the project but don't worry about including it anywhere

2) Add Apple's version of Reachability.h and Reachability.m to the project (you can get those here)

3) Add @class Reachability; to the .h file of where you are implementing the code

4) Create a couple instances to check in the interface section of the .h file:

Reachability* internetReachable;
Reachability* hostReachable;

5) Add a method in the .h for when the network status updates:

-(void) checkNetworkStatus:(NSNotification *)notice;

6) Add #import "Reachability.h" to the .m file where you are implementing the check

7) In the .m file of where you are implementing the check, you can place this in one of the first methods called (init or viewWillAppear or viewDidLoad etc):

-(void) viewWillAppear:(BOOL)animated
{
    // check for internet connection
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];

    internetReachable = [Reachability reachabilityForInternetConnection];
    [internetReachable startNotifier];

    // check if a pathway to a random host exists
    hostReachable = [Reachability reachabilityWithHostName:@"www.apple.com"];
    [hostReachable startNotifier];

    // now patiently wait for the notification
}

8) Set up the method for when the notification gets sent and set whatever checks or call whatever methods you may have set up (in my case, I just set a BOOL)

-(void) checkNetworkStatus:(NSNotification *)notice
{
    // called after network status changes
    NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
    switch (internetStatus)
    {
        case NotReachable:
        {
            NSLog(@"The internet is down.");
            self.internetActive = NO;

            break;
        }
        case ReachableViaWiFi:
        {
            NSLog(@"The internet is working via WIFI.");
            self.internetActive = YES;

            break;
        }
        case ReachableViaWWAN:
        {
            NSLog(@"The internet is working via WWAN.");
            self.internetActive = YES;

            break;
        }
    }

    NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
    switch (hostStatus)
    {
        case NotReachable:
        {
            NSLog(@"A gateway to the host server is down.");
            self.hostActive = NO;

            break;
        }
        case ReachableViaWiFi:
        {
            NSLog(@"A gateway to the host server is working via WIFI.");
            self.hostActive = YES;

            break;
        }
        case ReachableViaWWAN:
        {
            NSLog(@"A gateway to the host server is working via WWAN.");
            self.hostActive = YES;

            break;
        }
    }
}

9) In your dealloc or viewWillDisappear or similar method, remove yourself as an observer

-(void) viewWillDisappear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Note: There might be an instance using viewWillDisappear where you receive a memory warning and the observer never gets unregistered so you should account for that as well.


Note: The domain you use doesn't matter. It's just testing for a gateway to any domain.

Important Note: The Reachability class is one of the most used classes in projects so you might run into naming conflicts with other projects like ShareKit. If this happens, you'll have to rename one of the pairs of Reachability.h and Reachability.m files to something else to resolve the issue.

upvote
  flag
When they talk about the host being reachable, they are actually talking about whether or not a gateway to the host is reachable or not. They don't mean to say that "google.com" or "apple.com" is available, but moreso that a means of getting there is available. – iwasrobbed
upvote
  flag
My checkNetworkStatus method is not getting called.. I'm retaining in the init method. Anyone else have this trouble? – quantumpotato
upvote
  flag
Ah - have to call it manually, since the internet connection isn't "Changed" right when you start. In my ConnectionService init: _internetReachable = [[Reachability reachabilityForInternetConnection] retain]; [self checkNetworkStatus]; works. Thanks! +1 – quantumpotato
2 upvote
  flag
@gonzobrains: The domain you use doesn't matter. It's just testing for a gateway to any domain. – iwasrobbed
upvote
  flag
This example is using internetReachable, hostReachable as class members, which, for me, raises memory errors. I solved it by following Apple's example and accessing the object returned with the notification in the observer method. – Tudorizer
upvote
  flag
This is great - way better than what I was doing, which was using a built in WS ping method – tacos_tacos_tacos
upvote
  flag
So many Apple Mach-O Linker Error, can anyone make a simple project using this and post it up please? thanks – SeungUn Ham
upvote
  flag
Tip: Make sure no other libraries you have added already contain Reachability. I had linker errors only to realise Sharekit already had Reachability .h & .m included so I had them in the project twice. – Daniel Bowden
upvote
  flag
@gonzobrains There are places where google is not reachable for multiple reasons. – Coyote
upvote
  flag
Does WWAN include checking 3G connections? – Guy Daher
upvote
  flag
I already have existing Reachability files which are used by ShareKit. If I overwrite those files with the tonymillion version is my app going to break horribly? – Snowcrash
upvote
  flag
You using a BOOL, but if I copy your solution, the BOOL will always be false untill if I initialize it as True. Even when the BOOL is initialize before the notification come. – lagos
upvote
  flag
and don't forget to release internetReachable and hostReachable in your dealloc or viewWillDisappear or similar method – beryllium
upvote
  flag
I think this does not work correctly when phone is in airplane mode. Have any of you checked it? – Krishnan
upvote
  flag
how can one detect network changes if the app is in the background? – Hashmat Khalil
upvote
  flag
AFAIK, google.com is blocked in china - what happens to a user running this code in china? – Kaan Dedeoglu
1 upvote
  flag
@KaanDedeoglu It's just an example, use whatever domain you want. It simply checks for a gateway to the internet, not that the domain is actually available. – iwasrobbed
upvote
  flag
@iWasRobbed thank you for the clarification :) – Kaan Dedeoglu
upvote
  flag
Note... For approach 1, you'll need to add the "SystemConfiguration framework to the project", or you'll get errors like "_SCError, referenced from":", as detailed here: //allinonescript.com/a/11014062/26510 – Brad Parks
upvote
  flag
Not very reliable. What if google.com is down? </joke> – Nikolay Dyankov
1 upvote
  flag
Oh, btw you need to add SystemConfiguration.framework to the project as well (for method 1). – wiseindy
upvote
  flag
I'm an Android programmer learning iOS and I'm simply amazed that iOS doesn't have a simple built-in way of checking the internet connection! In Android SDK it's a one-liner. – Bogdan Alexandru
upvote
  flag
@BogdanAlexandru <insert comment here about how Android doesn't have simple built-in api either> – iwasrobbed
upvote
  flag
@iWasRobbed boolean is_internet_connection = (((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNet‌​workInfo() != null); – Bogdan Alexandru
upvote
  flag
@BogdanAlexandru I was speaking more broadly, like in-app purchases for example :) Or expansion files... Just have to be happy with what we have. – iwasrobbed
upvote
  flag
however, no method can detect those case that need to log in. – Jacky
upvote
  flag
@Jacky Huh? Detecting internet connection has nothing to do with storing user sessions for log in. – iwasrobbed
5 upvote
  flag
google.com doesn't work on China! – Dmitry
1 upvote
  flag
Use www.appleiphonecell.com instead of google.com - this url was created by apple for precisely this reason. – Smikey
upvote
  flag
What types of things are you all using to "Update the UI on the main thread" asynchronously in Method 1#4? NSNotificationCenter? – kraftydevil
upvote
  flag
Where to call testInternetConnection: or how many times to call it. I'm assuming only once? – kraftydevil
upvote
  flag
@iWasRobbed - ty. I found a blog post that spells out exactly what you're talking about: code.tutsplus.com/tutorials/… – kraftydevil
upvote
  flag
I used the Method 1 and trying to switch the Wifi on mac to check the status, strange is when wife disconnected unreachability block is called however' when Wifi made ON' the reachable block gets called , immediately the unreachable block calls as well. Why this error. – Vicky Dhas
upvote
  flag
It doesn't work if I am logged on an antenna wi-fi with no internet connection on it... – Claudio

I like to keep things simple. The way I do this is:

//Class.h
#import "Reachability.h"
#import <SystemConfiguration/SystemConfiguration.h>

- (BOOL)connected;

//Class.m
- (BOOL)connected
{
    Reachability *reachability = [Reachability reachabilityForInternetConnection];
    NetworkStatus networkStatus = [reachability currentReachabilityStatus];
    return networkStatus != NotReachable;
}

Then, I use this whenever I want to see if I have a connection:

if (![self connected]) {
    // Not connected
} else {
    // Connected. Do some Internet stuff
}

This method doesn't wait for changed network statuses in order to do stuff. It just tests the status when you ask it to.

upvote
  flag
Hi @msec, you can try Andrew Zimmer solution in this page, it works fine with adsl disconnected (and wifi connected) – Williew
upvote
  flag
WHY you are returning != NotReachable instead of "return netWorkStatus;" ??? – Fede Cugliandolo
1 upvote
  flag
For those who just copy and paste like i did with the above code. Also add SystemConfiguration.framework manually or you will get linking error. – Iftikhar
3 upvote
  flag
reachability undefined??? – coolcool1994

Using Apple's Reachability code, I created a function that'll check this correctly without you having to include any classes.

Include the SystemConfiguration.framework in your project.

Make some imports:

#import <sys/socket.h>
#import <netinet/in.h>
#import <SystemConfiguration/SystemConfiguration.h>

Now just call this function:

/*
Connectivity testing code pulled from Apple's Reachability Example: https://developer.apple.com/library/content/samplecode/Reachability
 */
+(BOOL)hasConnectivity {
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;

    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
    if (reachability != NULL) {
        //NetworkStatus retVal = NotReachable;
        SCNetworkReachabilityFlags flags;
        if (SCNetworkReachabilityGetFlags(reachability, &flags)) {
            if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
            {
                // If target host is not reachable
                return NO;
            }

            if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
            {
                // If target host is reachable and no connection is required
                //  then we'll assume (for now) that your on Wi-Fi
                return YES;
            }


            if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
                 (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
            {
                // ... and the connection is on-demand (or on-traffic) if the
                //     calling application is using the CFSocketStream or higher APIs.

                if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
                {
                    // ... and no [user] intervention is needed
                    return YES;
                }
            }

            if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
            {
                // ... but WWAN connections are OK if the calling application
                //     is using the CFNetwork (CFSocketStream?) APIs.
                return YES;
            }
        }
    }

    return NO;
}

And it's iOS 5 tested for you.

upvote
  flag
Can u describe this code? How does this check works? – Valery Pavlov
upvote
  flag
Works well on iOS3.0 too, thx – RocketMan
upvote
  flag
@JezenThomas This doesn't perform the internet check asynchronously, which is why it is "much slimmer"... You should always be doing this asynchronously by subscribing to notifications so that you don't hang up the app on this process. – iwasrobbed
upvote
  flag
Thanks, this work even if you are using wifi adsl and adsl is not connected, is exactly what I need. – Williew
4 upvote
  flag
This leaks memory - the 'readability' structure (object, thing) needs to be freed with CFRelease(). – Russell Mull
upvote
  flag
@RussellMull ... any idea how to fix the leak? – i_raqz
upvote
  flag
Weird that this answer predates mine (on a question marked as a duplicate) by 2 years, is exactly the same as mine, but I never saw it until today. – ArtOfWarfare
upvote
  flag
any ideas how to test connection to concrete IP and Port? Like "127.0.0.1:1535" – Artem Zaytsev

A version on Reachability for iOS 5 is darkseed/Reachability.h. It's not mine! =)

There's a nice-looking, ARC- and GCD-using modernization of Reachability here:

Reachability

You could use Reachability by  (available here).

#import "Reachability.h"

- (BOOL)networkConnection {
    return [[Reachability reachabilityWithHostName:@"www.google.com"] currentReachabilityStatus];
}

if ([self networkConnection] == NotReachable) { /* No Network */ } else { /* Network */ } //Use ReachableViaWiFi / ReachableViaWWAN to get the type of connection.

Here's a very simple answer:

NSURL *scriptUrl = [NSURL URLWithString:@"http://www.google.com/m"];
NSData *data = [NSData dataWithContentsOfURL:scriptUrl];
if (data)
    NSLog(@"Device is connected to the Internet");
else
    NSLog(@"Device is not connected to the Internet");

The URL should point to an extremely small website. I use Google's mobile website here, but if I had a reliable web server I'd upload a small file with just one character in it for maximum speed.

If checking whether the device is somehow connected to the Internet is everything you want to do, I'd definitely recommend using this simple solution. If you need to know how the user is connected, using Reachability is the way to go.

Careful: This will briefly block your thread while it loads the website. In my case, this wasn't a problem, but you should consider this (credits to Brad for pointing this out).

8 upvote
  flag
I really like this idea, but I would say for the 99.999% reliability while maintaining a small response size, go with www.google.com/m which is the mobile view for google. – rwyland
1 upvote
  flag
Awesome solution @Erik. What i also recommend you is to use www.google.com, instead of www.google.com/m, as rwyland said. It's weird, but from my test the mobile version always takes about 120ms more than the www.google.com – Sebyddd
2 upvote
  flag
Apple docs recommend not to do this since it can block the thread on a slow network, can cause app to be terminated in iOS – Brad Thomas
upvote
  flag
Thanks for the positive feedback, agree that www.google.com/m is the best solution because of reliability! – Erik Wegener
upvote
  flag
Also true that this will block the thread. That's why I'm using an extremely small website. Again, it's simple, not elegant. – Erik Wegener
upvote
  flag
do not use syncronous calls.. as Apple states. (and note that syncronsus call will wrap an asyn call.. :) ) – ingconti
upvote
  flag
dont use Async code "masked" as async. Doing do you can end up waiting forever (App stuck) if for example DNS are not set.. call will block indefinitely. – ingconti
- (void)viewWillAppear:(BOOL)animated
{
    NSString *URL = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];

    return (URL != NULL ) ? YES : NO;
}

Or use the Reachability class.

There are two ways to check Internet availability using the iPhone SDK:

1. Check the Google page is opened or not.

2. Reachability Class

For more information, please refer to Reachability (Apple Developer).

upvote
  flag
please take a bit more care of your formatting ... – kleopatra
1 upvote
  flag
There are two way to check internet availbility in iPhone SDK 1)Check the Google page is opened or not. – IOS Rocks
1 upvote
  flag
-1 : This is a synchronous method that will block the main thread (the one that the app UI is changed on) while it tries to connect to google.com. If your user is on a very slow data connection, the phone will act like the process is unresponsive. – iwasrobbed

Here is how I do it in my apps: While a 200 status response code doesn't guarantee anything, it is stable enough for me. This doesn't require as much loading as the NSData answers posted here, as mine just checks the HEAD response.

Swift Code

func checkInternet(flag:Bool, completionHandler:(internet:Bool) -> Void)
{
    UIApplication.sharedApplication().networkActivityIndicatorVisible = true

    let url = NSURL(string: "http://www.appleiphonecell.com/")
    let request = NSMutableURLRequest(URL: url!)

    request.HTTPMethod = "HEAD"
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
    request.timeoutInterval = 10.0

    NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.mainQueue(), completionHandler:
    {(response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in

        UIApplication.sharedApplication().networkActivityIndicatorVisible = false

        let rsp = response as! NSHTTPURLResponse?

        completionHandler(internet:rsp?.statusCode == 200)
    })
}

func yourMethod()
{
    self.checkInternet(false, completionHandler:
    {(internet:Bool) -> Void in

        if (internet)
        {
            // "Internet" aka Apple's region universal URL reachable
        }
        else
        {
            // No "Internet" aka Apple's region universal URL un-reachable
        }
    })
}

Objective-C Code

typedef void(^connection)(BOOL);

- (void)checkInternet:(connection)block
{
    NSURL *url = [NSURL URLWithString:@"http://www.appleiphonecell.com/"];
    NSMutableURLRequest *headRequest = [NSMutableURLRequest requestWithURL:url];
    headRequest.HTTPMethod = @"HEAD";

    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    defaultConfigObject.timeoutIntervalForResource = 10.0;
    defaultConfigObject.requestCachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;

    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue: [NSOperationQueue mainQueue]];

    NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:headRequest
        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
    {
        if (!error && response)
        {
            block([(NSHTTPURLResponse *)response statusCode] == 200);
        }
    }];
    [dataTask resume];
}

- (void)yourMethod
{
    [self checkInternet:^(BOOL internet)
    {
         if (internet)
         {
             // "Internet" aka Apple's region universal URL reachable
         }
         else
         {
             // No "Internet" aka Apple's region universal URL un-reachable
         }
    }];
}
3 upvote
  flag
Seems like this is the fastest way – Pavel
3 upvote
  flag
Caution: In my experience, this solution doesn't work all the time. In many cases the response returned is 403, after taking its sweet time. This solution seemed perfect, but doesn't guarantee 100% results. – Mustafa
upvote
  flag
Let's figure out a way to improve on the code and make it more perfect. – klcjr89
21 upvote
  flag
"No google , no internet" ?? – Kiran Ruth R
upvote
  flag
@KiranRuthR exactly! :) – klcjr89
upvote
  flag
Updated 2/6/14 with better implementation – klcjr89
7 upvote
  flag
As of June 2014, this will fail in mainland China, owing to the Chinese government now completely blocking google.com. (google.cn works, though, but in mainland China, no baidu.com, no internet) Probably better to ping whatever server you need to be communicating with. – prewett
2 upvote
  flag
China's loss. Oh well! – klcjr89
3 upvote
  flag
Use www.appleiphonecell.com instead - apple created this url for precisely this reason. – Smikey
upvote
  flag
@Smikey Google's url is more reliable than Apple's – klcjr89
upvote
  flag
But it doesn't work in China - this may be an issue for some people. And Apple created it precisely for testing network reachability on iPhone, so it is reliable. – Smikey
upvote
  flag
China's loss... – klcjr89
1 upvote
  flag
I used appleiphonecell as it is Apple's own, can be used in China as well, and it's a very fast website. This, in conjunction with your answer provided me with the nearest and fastest solution. Thank you – Septronic
upvote
  flag
May I suggest an update to your solution, as if there is an error or your block will never be called. (Also, I always check the block for nil, a it will crash if it is) -> BOOL isConnected = NO; if (!error && response) { isConnected = ([(NSHTTPURLResponse *)response statusCode] == 200); } if ( block ) { block(isConnected); } – eric
upvote
  flag
my previous comment was referring to the ObjectiveC solution – eric

If you're using AFNetworking you can use its own implementation for internet reachability status.

The best way to use AFNetworking is to subclass the AFHTTPClient class and use this class to do your network connections.

One of the advantages of using this approach is that you can use blocks to set the desired behavior when the reachability status changes. Supposing that I've created a singleton subclass of AFHTTPClient (as said on the "Subclassing notes" on AFNetworking docs) named BKHTTPClient, I'd do something like:

BKHTTPClient *httpClient = [BKHTTPClient sharedClient];
[httpClient setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)
{
    if (status == AFNetworkReachabilityStatusNotReachable) 
    {
    // Not reachable
    }
    else
    {
        // Reachable
    }
}];

You could also check for Wi-Fi or WLAN connections specifically using the AFNetworkReachabilityStatusReachableViaWWAN and AFNetworkReachabilityStatusReachableViaWiFi enums (more here).

2 upvote
  flag
By far the best solution, it needs more +1 – MegaManX
upvote
  flag
Thanks, @MegaManX – Bruno Koga
1 upvote
  flag
Please update the links on this thread. – Jamal Zafar
-(void)newtworkType {

 NSArray *subviews = [[[[UIApplication sharedApplication] valueForKey:@"statusBar"] valueForKey:@"foregroundView"]subviews];
NSNumber *dataNetworkItemView = nil;

for (id subview in subviews) {
    if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) {
        dataNetworkItemView = subview;
        break;
    }
}


switch ([[dataNetworkItemView valueForKey:@"dataNetworkType"]integerValue]) {
    case 0:
        NSLog(@"No wifi or cellular");
        break;

    case 1:
        NSLog(@"2G");
        break;

    case 2:
        NSLog(@"3G");
        break;

    case 3:
        NSLog(@"4G");
        break;

    case 4:
        NSLog(@"LTE");
        break;

    case 5:
        NSLog(@"Wifi");
        break;


    default:
        break;
}
}
6 upvote
  flag
Even if the device is connected to Wifi or some other network type, the internet connection can still be unavailable. Simple test: connect to your home wifi and then unplug your cable modem. Still connected to wifi, but zero internet. – iwasrobbed

First download the reachability class and put reachability.h and reachabilty.m file in your Xcode.

The best way is to make a common Functions class (NSObject) so that you can use it any class. These are two methods for a network connection reachability check:

+(BOOL) reachabiltyCheck
{
    NSLog(@"reachabiltyCheck");
    BOOL status =YES;
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(reachabilityChanged:)
                                          name:kReachabilityChangedNotification
                                          object:nil];
    Reachability * reach = [Reachability reachabilityForInternetConnection];
    NSLog(@"status : %d",[reach currentReachabilityStatus]);
    if([reach currentReachabilityStatus]==0)
    {
        status = NO;
        NSLog(@"network not connected");
    }
    reach.reachableBlock = ^(Reachability * reachability)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
        });
    };
    reach.unreachableBlock = ^(Reachability * reachability)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
        });
    };
    [reach startNotifier];
    return status;
}

+(BOOL)reachabilityChanged:(NSNotification*)note
{
    BOOL status =YES;
    NSLog(@"reachabilityChanged");
    Reachability * reach = [note object];
    NetworkStatus netStatus = [reach currentReachabilityStatus];
    switch (netStatus)
    {
        case NotReachable:
            {
                status = NO;
                NSLog(@"Not Reachable");
            }
            break;

        default:
            {
                if (!isSyncingReportPulseFlag)
                {
                    status = YES;
                    isSyncingReportPulseFlag = TRUE;
                    [DatabaseHandler checkForFailedReportStatusAndReSync];
                }
            }
            break;
    }
    return status;
}

+ (BOOL) connectedToNetwork
{
    // Create zero addy
    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)
    {
        NSLog(@"Error. Could not recover network reachability flags");
        return NO;
    }
    BOOL isReachable = flags & kSCNetworkFlagsReachable;
    BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
    BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
    NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"];
    NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL  cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
    NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];
    return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
}

Now you can check network connection in any class by calling this class method.

The Reachability class is OK to find out if the Internet connection is available to a device or not...

But in case of accessing an intranet resource:

Pinging the intranet server with the reachability class always returns true.

So a quick solution in this scenario would be to create a web method called pingme along with other webmethods on the service. The pingme should return something.

So I wrote the following method on common functions

-(BOOL)PingServiceServer
{
    NSURL *url=[NSURL URLWithString:@"http://www.serveraddress/service.asmx/Ping"];

    NSMutableURLRequest *urlReq=[NSMutableURLRequest requestWithURL:url];

    [urlReq setTimeoutInterval:10];

    NSURLResponse *response;

    NSError *error = nil;

    NSData *receivedData = [NSURLConnection sendSynchronousRequest:urlReq
                                                 returningResponse:&response
                                                             error:&error];
    NSLog(@"receivedData:%@",receivedData);

    if (receivedData !=nil)
    {
        return YES;
    }
    else
    {
        NSLog(@"Data is null");
        return NO;
    }
}

The above method was so useful for me, so whenever I try to send some data to the server I always check the reachability of my intranet resource using this low timeout URLRequest.

Use http://huytd.github.io/datatify/. It's easier than adding libraries and write code by yourself.

Get the Reachabilty class from https://github.com/tonymillion/Reachability, add the system configuration framework in your project, do import Reachability.h in your class and implement the custom methods as below:

- (BOOL)isConnectedToInternet
{
    //return NO; // Force for offline testing
    Reachability *hostReach = [Reachability reachabilityForInternetConnection];
    NetworkStatus netStatus = [hostReach currentReachabilityStatus];
    return !(netStatus == NotReachable);
}
3 upvote
  flag
-1; adds nothing to this thread that the accepted answer doesn't already cover better, IMO. Also, your entire method body can just be replaced with return [[Reachability reachabilityForInternetConnection] isReachable]; – Mark Amery

Import Reachable.h class in your ViewController, and use the following code to check connectivity:

     #define hasInternetConnection [[Reachability reachabilityForInternetConnection] isReachable]
     if (hasInternetConnection){
           // To-do block
     }
upvote
  flag
Your answer is exactly what I'm searching for. You sir deserves a vote up xD – Nikel Arteta

There is also another method to check Internet connection using the iPhone SDK.

Try to implement the following code for the network connection.

#import <SystemConfiguration/SystemConfiguration.h>
#include <netdb.h>

/**
     Checking for network availability. It returns
     YES if the network is available.
*/
+ (BOOL) connectedToNetwork
{

    // Create zero addy
    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)
    {
        printf("Error. Could not recover network reachability flags\n");
        return NO;
    }

    BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0);
    BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0);

    return (isReachable && !needsConnection) ? YES : NO;
}

To do this yourself is extremely simple. The following method will work. Just be sure to not allow a hostname protocol such as HTTP, HTTPS, etc. to be passed in with the name.

-(BOOL)hasInternetConnection:(NSString*)urlAddress
{
    SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [urlAddress UTF8String]);
    SCNetworkReachabilityFlags flags;
    if (!SCNetworkReachabilityGetFlags(ref, &flags))
    {
        return NO;
    }
    return flags & kSCNetworkReachabilityFlagsReachable;
}

It is quick simple and painless.

I found it simple and easy to use library SimplePingHelper.

Sample code: chrishulbert/SimplePingHelper (GitHub)

Apart from reachability you may also use the Simple Ping helper library. It works really nice and is simple to integrate.

First: Add CFNetwork.framework in framework

Code: ViewController.m

#import "Reachability.h"

- (void)viewWillAppear:(BOOL)animated
{
    Reachability *r = [Reachability reachabilityWithHostName:@"www.google.com"];
    NetworkStatus internetStatus = [r currentReachabilityStatus];

    if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
    {
        /// Create an alert if connection doesn't work
        UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle:@"No Internet Connection"   message:NSLocalizedString(@"InternetMessage", nil)delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [myAlert show];
        [myAlert release];
    }
    else
    {
         NSLog(@"INTERNET IS CONNECT");
    }
}

Very simple.... Try these steps:

Step 1: Add the SystemConfiguration framework into your project.


Step 2: Import the following code into your header file.

#import <SystemConfiguration/SystemConfiguration.h>

Step 3: Use the following method

  • Type 1:

    - (BOOL) currentNetworkStatus {
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        BOOL connected;
        BOOL isConnected;
        const char *host = "www.apple.com";
        SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, host);
        SCNetworkReachabilityFlags flags;
        connected = SCNetworkReachabilityGetFlags(reachability, &flags);
        isConnected = NO;
        isConnected = connected && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired);
        CFRelease(reachability);
        return isConnected;
    }
    

  • Type 2:

    Import header : #import "Reachability.h"

    - (BOOL)currentNetworkStatus
    {
        Reachability *reachability = [Reachability reachabilityForInternetConnection];
        NetworkStatus networkStatus = [reachability currentReachabilityStatus];
        return networkStatus != NotReachable;
    }
    

Step 4: How to use:

- (void)CheckInternet
{
    BOOL network = [self currentNetworkStatus];
    if (network)
    {
        NSLog(@"Network Available");
    }
    else
    {
        NSLog(@"No Network Available");
    }
}
upvote
  flag
Type 1 worked for me! – Haroldo Gondim

import "Reachability.h"

-(BOOL)netStat
{
    Reachability *test = [Reachability reachabilityForInternetConnection];
    return [test isReachable];
}

I think this one is the best answer.

"Yes" means connected. "No" means disconnected.

#import "Reachability.h"

 - (BOOL)canAccessInternet
{
    Reachability *IsReachable = [Reachability reachabilityForInternetConnection];
    NetworkStatus internetStats = [IsReachable currentReachabilityStatus];

    if (internetStats == NotReachable)
    {
        return NO;
    }
    else
    {
        return YES;
    }
}
  1. Download the Reachability file, https://gist.github.com/darkseed/1182373

  2. And add CFNetwork.framework and 'SystemConfiguration.framework' in framework

  3. Do #import "Reachability.h"


First: Add CFNetwork.framework in framework

Code: ViewController.m

- (void)viewWillAppear:(BOOL)animated
{
    Reachability *r = [Reachability reachabilityWithHostName:@"www.google.com"];
    NetworkStatus internetStatus = [r currentReachabilityStatus];

    if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
    {
        /// Create an alert if connection doesn't work
        UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle:@"No Internet Connection"   message:NSLocalizedString(@"InternetMessage", nil)delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [myAlert show];
        [myAlert release];
    }
    else
    {
         NSLog(@"INTERNET IS CONNECT");
    }
}

Create an object of AFNetworkReachabilityManager and use the following code to track the network connectivity

self.reachabilityManager = [AFNetworkReachabilityManager managerForDomain:@"yourDomain"];
[self.reachabilityManager startMonitoring];
[self.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
            case AFNetworkReachabilityStatusReachableViaWWAN:
            case AFNetworkReachabilityStatusReachableViaWiFi:
                break;
            case AFNetworkReachabilityStatusNotReachable:
                break;
            default:
                break;
        }
    }];
  • Step 1: Add the Reachability class in your Project.
  • Step 2: Import the Reachability class
  • Step 3: Create the below function

    - (BOOL)checkNetConnection {
        self.internetReachability = [Reachability reachabilityForInternetConnection];
        [self.internetReachability startNotifier];
        NetworkStatus netStatus = [self.internetReachability currentReachabilityStatus];
        switch (netStatus) {
            case NotReachable:
            {
                return NO;
            }
    
            case ReachableViaWWAN:
            {
                 return YES;
            }
    
            case ReachableViaWiFi:
            {
                 return YES;
            }
        }
    }
    
  • Step 4: Call the function as below:

    if (![self checkNetConnection]) {
        [GlobalFunctions showAlert:@""
                         message:@"Please connect to the Internet!"
                         canBtntitle:nil
                         otherBtnTitle:@"Ok"];
        return;
    }
    else
    {
        Log.v("internet is connected","ok");
    }
    
upvote
  flag
Apple's docs state this Note: Reachability cannot tell your application if you can connect to a particular host, only that an interface is available that might allow a connection, and whether that interface is the WWAN. – noobsmcgoobs

Checking the Internet connection availability in (iOS) Xcode 8 , Swift 3.0

This is simple method for checking the network availability like our device is connected to any network or not. I have managed to translate it to Swift 3.0 and here the final code. The existing Apple Reachability class and other third party libraries seemed to be too complicated to translate to Swift.

This works for both 3G,4G and WiFi connections.

Don’t forget to add “SystemConfiguration.framework” to your project builder.

//Create new swift class file Reachability in your project.
import SystemConfiguration
public class InternetReachability {

class func isConnectedToNetwork() -> Bool {
   var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
   zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
   zeroAddress.sin_family = sa_family_t(AF_INET)
   let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
          SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)).takeRetainedValue()
   }
   var flags: SCNetworkReachabilityFlags = 0
   if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == 0 {
          return false
   }
   let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0
   let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0

   return isReachable && !needsConnection
  }
}

// Check network connectivity from anywhere in project by using this code.
 if InternetReachability.isConnectedToNetwork() == true {
         print("Internet connection OK")
  } else {
         print("Internet connection FAILED")
  }

This is for SWIFT 3.0 and async. Most answers are sync solution which is gonna block your main thread if you have a very slow connection. This solution is better but not perfect because it rely on Google to check the connectivity so feel free to use an other url.

func checkInternetConnection(completionHandler:@escaping (Bool) -> Void)
{
    if let url = URL(string: "http://www.google.com/")
    {
        var request = URLRequest(url: url)
        request.httpMethod = "HEAD"
        request.cachePolicy = .reloadIgnoringLocalAndRemoteCacheData
        request.timeoutInterval = 5

        let tast = URLSession.shared.dataTask(with: request, completionHandler:
        {
            (data, response, error) in

            completionHandler(error == nil)
        })
        tast.resume()
    }
    else
    {
        completionHandler(true)
    }
}

Try this:

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error


if ([self.delegate respondsToSelector:@selector(getErrorResponse:)]) {
    [self.delegate performSelector:@selector(getErrorResponse:) withObject:@"No Network Connection"];
}

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"BMC" message:@"No Network Connection" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK",nil];
[alertView show];

}

upvote
  flag
At minimum add an explanation what this code does and how it solves the problem. – Mark Rotteveel

Swift 3

You must first import

import SystemConfiguration

You can check internet connection with the following method

func isConnectedToNetwork() -> Bool {

    var zeroAddress = sockaddr_in()
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)

    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
        }
    }

    var flags = SCNetworkReachabilityFlags()
    if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
        return false
    }
    let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
    let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
    return (isReachable && !needsConnection)

}

Not the answer you're looking for? Browse other questions tagged or ask your own question.