Tutorial :Checking For Internet Connectivity in Objective C



Question:

I've been working through the Stanford iPhone Coding course and currently hooking into the Twitter API. What I'd like to do is accurately handle two error conditions: One for when the username is invalid, and another for when the device is not currently connected to the internet. Unfortunately, as it stands, the best I can surmise is whether or not the return from the API is nil or not - which is the case for both conditions.

What I'm looking for is a line or two of code that can check for a connection before attempting any fetch of remote data. I could sift through the Apple documentation but I figured: Why not put the question to you guys for my benefit and perhaps that of others?

Additional info: Using Objective-C and the iPhone SDK in XCode.


Solution:1

Take a look at Apple's sample code. The Reachability project shows how to detect a connection.

http://developer.apple.com/iphone/library/samplecode/Reachability/index.html


Solution:2

That code works, but doesn't always create the desired result.

The way that the TCP stack on the iPhone works is very different from what should be expected. With the "Reachability" code, sometimes a network connection will be present, but will not be reliably detected. However, launching MobileSafari then reattempting to check connectivity with "Reachability" code will result in the correct result.

The way that I have found most effective in determining network connectivity is to run a NSURLConnection check when the application loads, in a separate thread. Make a call to a URL that you know will return something like "Yes" (i.e. HTML file on your server or something). Then check to be sure the returned result is equal to the static text. That way, you know that the NSURLConnection stack is reaching out properly, as opposed to the "Reachability" code that does not quite work consistently.


Solution:3

You'll need to read in the error codes and respond as best you can. I've had some experience with this essentially it may depend on what service you are interacting with but with delicious.com I get error -1012 for bad user/passwd which if you look it up is

NSURLErrorUserCancelledAuthentication =     -1012,  

though clearly that wording is misleading, though I can consistently replicate putting in bad user/passwd and getting that error code. Technically the iPhone is never not connected to the internet unless you are in some strange region that has problems with data connection. I see also there is an error code

NSURLErrorNotConnectedToInternet =      -1009,  

I would go through NSURLError.h (and there are more like that)

NSURLErrorUnsupportedURL =          -1002,  NSURLErrorCannotFindHost =          -1003,  NSURLErrorCannotConnectToHost =         -1004,  NSURLErrorNetworkConnectionLost =       -1005,  

etc...

all you need to do is get a reference to the NSError object you passed in & check it's error code like so

//NSError *returnedError    if([returnedError code] == kERROR_CODE_BAD_USERNAME_OR_PASSWORD)  

the constant is something i've defined in my own source code that is essentially -1012


Solution:4

this works for me and is taken from apple seismic xml project:

- (BOOL)isDataSourceAvailable  {      static BOOL checkNetwork = YES;      if (checkNetwork) { // Since checking the reachability of a host can be expensive, cache the result and perform the reachability check once.          checkNetwork = NO;            Boolean success;              const char *host_name = "twitter.com"; // your data source host name            SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, host_name);          SCNetworkReachabilityFlags flags;          success = SCNetworkReachabilityGetFlags(reachability, &flags);          _isDataSourceAvailable = success && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired);          CFRelease(reachability);      }      return _isDataSourceAvailable;  }  


Solution:5

reachability is separate class through you can access the code

   Reachability *curReach = [Reachability reachabilityForInternetConnection];  NetworkStatus netStatus = [curReach currentReachabilityStatus];  switch (netStatus)  {      case NotReachable:      {          UIAlertView *connectionAlert = [[UIAlertView alloc] init];          [connectionAlert setTitle:@"Error"];          [connectionAlert setMessage:@"Please check your network connection."];          [connectionAlert setDelegate:self];          [connectionAlert setTag:1];          [connectionAlert addButtonWithTitle:@"Back"];          [connectionAlert show];            break;      }      case ReachableViaWWAN:      {          }      case ReachableViaWiFi:      {      }  }  


Solution:6

What's your current connection code look like? If you're using NSURLConnection +sendSynchronousRequest:returningResponse:error:, then you just need to pass the address of an NSError variable and check that thereafter; with connectionWithRequest:delegate:, you should implement -connection:didFailWithError: in the delegate.


Solution:7

When using Apple's Reachability bear in mind that you can find yourself being connected via WWAN (ReachableViaWWAN) or WiFi (ReachableViaWiFi) without being connected to the internet even when you try to reach some host like google.com or apple.com (maybe a caching issue). I ended up calling my own server and getting back a digit - the best solution in my case at least.


Solution:8

-(BOOL)returnInternetConnectionStatus{      ReachabilityLattest *reach = [ReachabilityLattest reachabilityForInternetConnection];      NetworkStatus internetStatus = [reach currentReachabilityStatus];      if ((internetStatus != NotReachable)) {          return TRUE;      } else {          return FALSE;      }  }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »