I am using the following method to check if my app has a connection. It's simple and works great for my needs.
+ (void)checkInternet:(connection)block
{
NSURL *url = [NSURL URLWithString:@"http://www.google.com/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"HEAD";
request.cachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
request.timeoutInterval = 10.0;
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
block([(NSHTTPURLResponse *)response statusCode] == 200);
}];
}
However, what I'd like to do is if the status doesn't return 200, I'd like to check again, at least a couple of times. What's the best way to do this with 1 second intervals?
Below is how I'm calling the above method.
[self checkInternet:^(BOOL internet)
{
if (internet)
{
// "Internet" aka Google
}
else
{
// No "Internet" aka no Google
}
}];
I use Reachability for detecting general network connection issues (See end of answer). I use the following method for executing retries.
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
You could adapt your system something like the following to have a new class method which has an optional number of retries.
NB. Not tested the following. It is just to give you the general idea.
// Variable to track number of retries left. If you had a shared instance
// a property would be easier.
static NSUInteger maxConnectionTries = 0;
// New method which lets you pass a retry count.
+ (void)checkInternet:(connection)block withMaxTries:(NSUInteger)maxTries
{
maxConnectionTries=maxTries;
[self checkInternet:block];
}
// Your original code extended to retry by calling itself when code 200
// is seen on a delay of 1s. Defaults to old code when retry limit exceeded
// or non 200 code received.
+ (void)checkInternet:(connection)block
{
NSURL *url = [NSURL URLWithString:@"http://www.google.com/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"HEAD";
request.cachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
request.timeoutInterval = 10.0;
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:
^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
if ([(NSHTTPURLResponse *)response statusCode] != 200 &&
maxConnectionRetries > 0){
maxConnectionRetries--;
[self performSelector:@selector(checkInternet:) withObject:block afterDelay:1.0];
}
else{
maxConnectionRetries = 0;
block([(NSHTTPURLResponse *)response statusCode] == 200);
}
}];
}
For general detection of internet connectivity, it is best to use Reachability. See here.
I start a reachability handler from my AppDelegate code and then publish local notifications when connectivity changes occur. This allows the application to always receive connection change notification and transient view controllers within viewWillAppear
and viewWillDisappear
to register and deregister for local notifications if they are interested in connection changes.