12

Which is the best way to check the Internet connection using the iOS SDK?

0

3 Answers 3

36

Best way is to use Reachability code. Check here for apple sample code. That has a lot of convenience methods to check internet availability, Wifi/WAN connectivity check etc..

For eg:-

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkChanged:) name:kReachabilityChangedNotification object:nil];

reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];

- (void)networkChanged:(NSNotification *)notification
{

  NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

  if(remoteHostStatus == NotReachable) { NSLog(@"not reachable");}
  else if (remoteHostStatus == ReachableViaWiFiNetwork) { NSLog(@"wifi"); }
  else if (remoteHostStatus == ReachableViaCarrierDataNetwork) { NSLog(@"carrier"); }
}
Sign up to request clarification or add additional context in comments.

2 Comments

ReachableViaCarrierDataNetwork & ReachableViaWiFiNetwork are not available, status can be ReachableViaWWAN or ReachableViaWiFi.
after notification only it shows but it need before the network changes. how to get the available network when viewdidload method calls..
13

Reachability has a lot more to it than it needs, plus it hasn't been updated for ARC yet.

Here's my solution in pure C. Much of the code was taken directly from Reachability, but distilled down to only what is necessary. I only wanted it to return whether there was or wasn't an internet connection, but you can read from the comments whether it's returning YES based on having found a Wifi or a Cellular network.

One last note before proceeding to share the code: You need to go into your build target, select the build phases tab, and add "SystemConfiguration.framework" to the "Link Binary With Libraries" list.

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

BOOL networkReachable()
{
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;

    SCNetworkReachabilityRef reachabilityRef = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *) &zeroAddress);

    SCNetworkReachabilityFlags flags;
    if (SCNetworkReachabilityGetFlags(reachabilityRef, &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; // This is a wifi connection.
        }


        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; // This is a wifi connection.
            }
        }

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

    return NO;
}

2 Comments

I like your solution a lot, but personally I'd do a small modification. I think instead of returning a BOOL you should return a constant or ENUM element, just so we can identify if there's a connection and what type. Luckily this modification is not hard to do!
I believe I have made a mistake here and that this code leaks. The SCNetworkReachabilityRef needs to be sent to CFRelease() at some point... the best way of doing this may be to break out the SCNetworkReachabilityGetFlags() and store its value, then release the reachability ref, then proceed to the if and check the stored value. That way the memory occupied by the SCNetworkReachability stored on the heap is released, but everything you need at that point (the flags and the return value of SCNetworkReachabilityGetFlags()) are still available on the stack.
10

Try this code:

- (BOOL)connectedToInternet
{
   NSURL *url=[NSURL URLWithString:@"http://www.google.com"];
   NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
   [request setHTTPMethod:@"HEAD"];
   NSHTTPURLResponse *response;
   [NSURLConnection sendSynchronousRequest:request returningResponse:&response error: NULL];

   return ([response statusCode]==200)?YES:NO;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.