1

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.

Charith Nidarsha
  • 3,827
  • 3
  • 26
  • 31

4 Answers4

3

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

Greg
  • 32,510
  • 15
  • 88
  • 99
  • Note that the Reachability class was actually provided by Apple, ASI just includes it because they also make use of it. – Kendall Helmstetter Gelner Mar 24 '11 at 03:56
  • Actually, per the ASI documentation, "This class was written by Andrew Donoho as a drop-in replacement for Apple’s Reachability class." The blog post I linked to explains why he re-engineered the Reachability class. – Greg Mar 24 '11 at 04:02
  • Thanks for the clarification, I did not realize that. Curse him for leaving the name "Reachability" which conflicts with the Apple class if you are using it. I'll read the blog post and see what is going on there. – Kendall Helmstetter Gelner Mar 24 '11 at 04:06
2

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.

Adam Eberbach
  • 12,227
  • 6
  • 59
  • 112
1

This is how I did it:

  1. Obtain the Readability.h/m from the Apple Sample Projects and place it in your project
  2. Install the NetworkObserver.h/m below
  3. When the App starts in the ["AppDelegate" didFinishLaunchingWithOptions] start the NetworkObserver with [[NetworkObserver currentObserver] start]
  4. When the App goes into the background (applicationDidEnterBackground) stop it and when it goes into the foreground (applicationWillEnterForeground) then start it again
  5. When you need to test it then use this code:

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.

Community
  • 1
  • 1
Andy S.
  • 533
  • 2
  • 6
  • You said:"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." Is there any way we can know that the it has updated the values of "hostActive" variable ??? – viral Aug 16 '12 at 06:27
0

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.

Nathan Jones
  • 1,806
  • 14
  • 13