22

I use AFNetworking in my app for every request (like login, get data from url, etc).

Take this for example: an user click on the login button and there's no connection, how to instantly display a UIAlertView that says the error? The only way is to wait the request timeout and execute the failure block? Isn't there a way that instantly check if there's connection or not?

Thanks!

Fred Collins
  • 5,004
  • 14
  • 62
  • 111

5 Answers5

56

As of 0.9, AFHTTPClient actually has network reachability built-in (a simpler interface to Apple's aforementioned Reachability code). Just include the SystemConfiguration framework and use -setReachabilityStatusChangeBlock: to specify a response when the reachability state changes.

mattt
  • 19,544
  • 7
  • 73
  • 84
  • 1
    Hi mattt and thanks for you reply. But your suggestion is to check for current status of internet connection before **every** method that uses internet and if there's no connection displays an alert? – Fred Collins Feb 13 '12 at 05:22
  • 3
    No, not at all. `AFHTTPClient` monitors for reachability changes and executes the specified block when that happens. The block has a single argument, which is a boolean for whether or not the `baseURL` is reachable. – mattt Feb 13 '12 at 05:33
  • 1
    I've subclassed `AFHTTPClient` and I've overridden `-setReachabilityStatusChangeBlock:` with an `NSLog(@"test")` inside but the statement is never executed. Why? – Fred Collins Feb 15 '12 at 05:01
  • @FredCollins Check that you've included the SystemConfiguration framework. If that's not linked to the project, that code won't run. – mattt Feb 16 '12 at 21:41
  • @mattt could you add some sample code so I could see what should I do. Thanks – Simon Apr 24 '12 at 23:17
  • 1
    @FredCollins You don't override the method, you call it on your subclass and pass in a block which contains the code you want to run. Make sure you take out your override or it WILL NOT WORK. – Lance May 21 '12 at 23:39
  • 9
    Add `#import ` to the header prefix of the project (Prefix.pch). This is required step after adding SystemConfiguration framework. – Avinash Jun 26 '12 at 08:17
  • 3
    @mattt I have set `setReachabilityStatusChangeBlock:` before setting up a `JSONRequestOperationWithRequest:success:failure`, is this the right way to do it? if that's the case, when I get a status of `AFNetworkReachabilityStatusNotReachable`, how do I cancel the operation, or would the failure block be automatically called when it sees a `AFNetworkReachabilityStatusNotReachable`? – minovsky Oct 27 '12 at 08:18
28

With AFNetworking these are the steps that one has to follow in order to take advantage of setReachabilityStatusChangeBlock: after adding the AFNetworing classes -

  1. Add SystemConfiguration.framework to your project
  2. In pch file add #import <SystemConfiguration/SystemConfiguration.h>
  3. Assuming that you have a subclass of AFHTTPClient in this subclass add below lines of code in init function -
[self setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        NSLog(@"changed %d", status);
        //your code here
    }];
Hemang
  • 26,840
  • 19
  • 119
  • 186
Yogesh Agarwal
  • 2,610
  • 3
  • 27
  • 31
2

I use the AFNetworkingOperationDidFinishNotification. Every time a http request will fail, the alert pops up and informs the user

- (void)addNetworkObserver
{
   [[NSNotificationCenter defaultCenter] addObserver:self
                                            selector:@selector(HTTPOperationDidFinish:) 
                                                name:AFNetworkingOperationDidFinishNotification 
                                              object:nil];
}

- (void)HTTPOperationDidFinish:(NSNotification *)notification 
{
   AFHTTPRequestOperation *operation = (AFHTTPRequestOperation *)[notification object];
   if (![operation isKindOfClass:[AFHTTPRequestOperation class]]) {
       return;
   }
   if (operation.error) {
       UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Connection error"
                                                       message:@"Missing connection to the internet"
                                                      delegate:nil
                                             cancelButtonTitle:@"OK"
                                             otherButtonTitles:nil];

       [alert show];
   }
}
iphonic
  • 12,615
  • 7
  • 60
  • 107
Carmen
  • 6,177
  • 1
  • 35
  • 40
2

Maybe you could use "Reachability" to determine if the device is connected to the network. Here is the link to the Apple Doc. : Reachability

For example :

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNetworkChange:) name:kReachabilityChangedNotification object:nil];
reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];
if(remoteHostStatus == NotReachable) {
  //Your UIAlertView
}
bs7
  • 627
  • 4
  • 11
0

How about using Reachability?

You can check whether you have a plausible reason for trying a connection before you do it.

Looks like the Apple Sample Project for Reachability shows how to get an initial status.

Community
  • 1
  • 1
Adam Eberbach
  • 12,309
  • 6
  • 62
  • 114
  • For any case where reachability returns no, won't any socket i/o fail immediately, too? – smparkes Feb 12 '12 at 23:04
  • Yes, that's how Reachability works but it gives you extras like the ability to receive notifications when reachability changes - interrupts, not polling. – Adam Eberbach Feb 12 '12 at 23:18
  • Excuse me Adam, but if the network is not used but the device is connected and I check for network status, Reachability tell me I've no connection. This answer explain what I would say in a better way: http://stackoverflow.com/a/9186073/719127 – Fred Collins Feb 12 '12 at 23:22
  • Right. I guess my point was for the question at hand, using reachability isn't any better than just trying to make the connection. – smparkes Feb 12 '12 at 23:27
  • Updated with a link to the code sample - checking reachability before making your actual request can be done. – Adam Eberbach Feb 12 '12 at 23:40
  • Thanks guy, I'll try to implement it in while and I come back with the response. :-) – Fred Collins Feb 13 '12 at 01:18