4

I have an application that requires an internet connection for a certain library I use (XIMSS for Communigate). It receives status updates from a server and I can't alter the source of the lib. Is there a way to detect that the device disconnected from the internet? I'd like to avoid having to ping a server every x seconds to see if there is still a connection.

Adam Johns
  • 32,040
  • 21
  • 108
  • 161
Kevin
  • 2,639
  • 29
  • 56

4 Answers4

8

Apple's Reachability does this for you. Notifies you as your connectivity changes.

Rob
  • 371,891
  • 67
  • 713
  • 902
  • Thanks, do you know if this does a request? Even if pings are just a few bytes, my application will be running 24/7 and some users will be using 3g, so I want to have as little traffic as possible. – Kevin Aug 13 '13 at 12:43
  • @Kevin Maybe initially, but it's not polling, if that's what you're asking. It uses the SystemConfiguration.framework to detect changes. You'll get a notification as network connectivity changes. – Rob Aug 13 '13 at 13:01
  • Over two years later now, and I gotta say Reachability is a piece of shit. So bad in fact, that [several people have written their own classes with the same purpose](https://www.google.nl/search?q=reachability&oq=reachability&aqs=chrome..69i57.1855j0j4&sourceid=chrome&es_sm=91&ie=UTF-8#q=reachability+github). – Kevin Feb 24 '16 at 13:00
3

In iOS you can check like that :-

-(BOOL)returnInternetConnectionStatus{

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

For more detail you can download from here Reachability Sample Code

Hope this helps you !

Arpit Kulsreshtha
  • 2,442
  • 2
  • 24
  • 50
3

Note that all the pointers to Reachability are a good start, and you definitely need Reachability, but for a messaging app it is generally not sufficient. Reachability never sends packets. It just tells you whether the device could even try to send a packet if you asked it to. So it basically tells you that you have an IP address and know a gateway. It does not tell you that you could reach the server you care about, and it absolutely does not tell you whether that server can reach you (which is a very important question for messaging apps).

In most cases, if Reachability were sufficient, you wouldn't need Reachability. Apple strongly recommends (and for good reason) that you not check Reachability before sending packets. Just send the packets and deal with the error if it comes. But that doesn't help for apps that have to receive data at random times.

If connectivity is poor (particularly due to poor cell coverage), or if there is a firewall between you and the server, you can easily get positive results from Reachability even though you are no longer getting messages from the server. The only way to detect this situation is to send a packet and receive a packet (i.e. "ping").

Reachability is also not sufficient to notice when your connection changes. For instance, if you change IP addresses (pretty common when you're driving around town), Reachability won't always tell you (it may if you use SCNetworkReachabilityCreateWithAddressPair(); it's been awhile since I've worked on this problem; but the Reachability example code doesn't work this way in any case).

So Reachability is a good first start, but at the end of the day you still require a heartbeat if you want to detect that the server is no longer talking to you. The key thing to remember is that in IP, there is no such thing as "a connection." There are just packets. You can send them and you can receive them. But if you aren't receiving them, there's no way to distinguish "no one is sending them" from "they are not arriving." The illusion TCP gives of "connections" only exists when packets are being exchanged.

(BTW, dealing with network connectivity in a messaging app is probably the hardest iOS code I've ever worked on. Testing is a nightmare. I used to stick my phone in the fridge to cut off its network access. At least now there is the network conditioner…)

Rob Napier
  • 250,948
  • 34
  • 393
  • 528
  • Thank you for the information. The library I'm using has it's own timeout functions with proper callbacks which I can override, so in my case reachability is fine. The only problem I had is that the lib's timeout is 30 seconds, and I want to notify the user sooner, because there is real time presence involved. In any case +1 for the clear explanation. – Kevin Aug 13 '13 at 14:01
0
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ReachablilityChange:) name:kReachabilityChangedNotification object:nil];

Add notifier for Reachability Change Notification.This will call the reachabilityChange when the network change occur, In ReachablilityChange function detect

 NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];

Get status in hostStatus

    if(hostStatus == NotReachable)

{Do your code here;}

Gobi M
  • 3,035
  • 4
  • 29
  • 44