I have an iPad application which connects to a web server. I need to check whether the web server is running at that time. If the web server is down I have to prompt a message to the user. How would I do this?
Thanks.
I have an iPad application which connects to a web server. I need to check whether the web server is running at that time. If the web server is down I have to prompt a message to the user. How would I do this?
Thanks.
I've used the Reachability class included with the ASIHttpRequest library quite successfully to verify that a particular server is reachable over the network. This blog post describes how to go about doing this: http://blog.ddg.com/?p=24
You should construct the NSURLRequest with a timeout value (requestWithURL:cachePolicy:timeoutInterval:
) to handle no response at all. If the timeout value is reached you will get the delegate callback didFailWithError:
.
If you don't get that, eventually the NSURLConnection should get you a didReceiveResponse:
. There you need to interpret the NSURLResponse code where you can process the usual HTTP response codes (200, 404, 500 etc.)
This is a different problem to determining whether you have any internet connection at all - you should look into including Apple's Reachability code sample for that.
This is how I did it:
Code on how to use it:
NetworkObserver *observer = [NetworkObserver currentNetworkObserver];
if( observer.internetActive && observer.hostActive ) {
// Do whatever you need to do with the Network
} else {
if( !observer.internetActive ) {
if( anError ) {
*anError = [NSError errorWithDomain:NetworkErrorDomain code:1212 userInfo:[NSDictionary dictionaryWithObject:@"Internet is not active at the moment" forKey:NSLocalizedDescriptionKey]];
}
} else {
if( anError ) {
*anError = [NSError errorWithDomain:NetworkErrorDomain code:1221 userInfo:[NSDictionary dictionaryWithObject:@"Host is cannot be reached" forKey:NSLocalizedDescriptionKey]];
}
}
}
First here is the code for NetworkObserver.h
#import <Foundation/Foundation.h>
@class Reachability;
@interface NetworkObserver : NSObject {
@private
BOOL internetActive;
BOOL hostActive;
Reachability* internetReachable;
Reachability* hostReachable;
}
@property (nonatomic) BOOL internetActive;
@property (nonatomic) BOOL hostActive;
@property (nonatomic, retain) Reachability* internetReachable;
@property (nonatomic, retain) Reachability* hostReachable;
// Checks the current Network Status
- (void) checkNetworkStatus:(NSNotification *)notice;
- (void) start;
- (void) stop;
+ (NetworkObserver *) currentNetworkObserver;
@end
Finally the code for the NetworkObserver.m:
#import "NetworkObserver.h"
#import "Reachability.h"
#import "Constants.h"
static NetworkObserver *networkObserver;
@implementation NetworkObserver
@synthesize internetReachable, hostReachable;
@synthesize internetActive, hostActive;
+(void) initialize {
if( !networkObserver ) {
networkObserver = [[NetworkObserver alloc] init];
}
}
+ (NetworkObserver *) currentNetworkObserver {
return networkObserver;
}
- (id) init {
self = [super init];
if( self ) {
self.internetReachable = [[Reachability reachabilityForInternetConnection] retain];
// check if a pathway to a random host exists
DLog( @"NO.init(), host name: %@", kServerHostName );
self.hostReachable = [[Reachability reachabilityWithHostName:kServerHostName] retain];
}
return self;
}
- (void) start {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];
[internetReachable startNotifier];
[hostReachable startNotifier];
[self checkNetworkStatus:nil];
}
- (void) stop {
[internetReachable stopNotifier];
[hostReachable stopNotifier];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void) checkNetworkStatus:(NSNotification *)notice
{
// called after network status changes
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
switch (internetStatus)
{
case NotReachable:
{
DLog(@"The internet is down.");
self.internetActive = NO;
break;
}
case ReachableViaWiFi:
{
DLog(@"The internet is working via WIFI.");
self.internetActive = YES;
break;
}
case ReachableViaWWAN:
{
DLog(@"The internet is working via WWAN.");
self.internetActive = YES;
break;
}
}
if( notice ) {
NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
switch (hostStatus)
{
case NotReachable:
{
DLog(@"A gateway to the host server is down.");
self.hostActive = NO;
break;
}
case ReachableViaWiFi:
{
DLog(@"A gateway to the host server is working via WIFI.");
self.hostActive = YES;
break;
}
case ReachableViaWWAN:
{
DLog(@"A gateway to the host server is working via WWAN.");
self.hostActive = YES;
break;
}
}
} else {
DLog(@"No notice received yet so assume it works");
self.hostActive = YES;
}
}
@end
By the way just replace DLog with NSLog to make it work (I use this a preprocessor instruction to take NSLog out when I release the App).
On the other hand there are many other post on Stack OverFlow that deal with that issue like this one.
Also note that it takes a little tim for the NetworkObserver to get the right values so you might not be able to use it when it starts.
I would think the easiest solution would be to create a test file that you could ping. Perhaps something like serverping.txt with nothing more than 'ok' as it's contents (to keep the data load to a minimum). If your response statusCode is 503 (or perhaps 500...you'd have to test), then you know the service is unavailable.