What is the advantage of using Reachability? What is the advantage of using Reachability? ios ios

What is the advantage of using Reachability?

This is actually quite a good question - so good that I actually use it in iOS developer interviews when my company is recruiting:

Why is Apple's reachability example hundreds of lines long, when you can just use a single line to check if a URL is responsive?

Firstly, network reachability is actually very, very complicated. It's much more than simply testing for a URL. Think about the following examples:

  • The user is on 3G, but has used up their data allowance, so everyrequest redirects to the carrier's site.

  • The user is connected to a public WiFi network that requiresauthentication / login, so the request redirects to a log in page

The last example is incredibly common - it happens all the time. But if you used initWithContentsOfURL your app would imagine you had connectivity, when in fact you didn't: you would simply have been returned the contents of the page the network had redirected you to.

This is one reason why Apple's code is more complex than you might at first think it needs to be. You shouldn't just be asking "can I reach this URL", but "is the data being returned from this URL what I expect it to be".

But that's really just the tip of the iceberg. Reachability does a lot more besides that - for example, I might have an app that needs to download a lot of information, say 50MB worth. It would be a bad idea to simply download 50MB of data if the user was on a 3G connection without their consent - especially if they are roaming, or on a restricted data plan. So Reachability will also tell you what type of connection the user is on: EDGE, 3G, WiFi, etc (*NB: see the note below, this is probably not the best advice).

The ReadMe.txt inside Reachability will tell you a little more about what the code can and can't do.

Unfortunately, there are all too many people online who don't realise that there are many everyday scenarios where initWithContentsOfURL will return a valid response but the user won't have connectivity. [Blog posts like this][1] get indexed in Google, and people assume it's an acceptable substitute: it's not!

One of the reasons I ask this question when recruiting is it can show a developer is not just thinking inside the box - like you and many other developers, my first reaction when I saw the Reachability sample code was "wow, this seems way too complicated for something that's very simple". But hopefully this answer will have gone some way to convincing you otherwise.

Edit: Definitely take note of Steven's comments below. He raises some points that my answer hadn't considered (i.e., MiFi hotspots), and makes a valid case that Reachability isn't necessarily the peak of coding heaven it code be. In many cases developers will modify Reachability with their own improvements and the like.

Reachability's biggest problem isn't that it's bad code, or that it's bad code to use. It's actually fairly nice code now. But it's easy code to misunderstand and misuse for a purpose it wasn't intended.

Here are some guidelines for using Reachability:

  • Yes, use Reachability. Maybe the most obvious point: Reachability can be a huge asset to making your app feel more natural.
  • Never use Reachability as a preflight check. Just because Reachability is reporting networking isn't currently available doesn't mean it won't become available if you try to use it. That network request you're not sending could be the very thing that wakes up iOS's networking.
    • Edit: Actually, I probably should soften this a bit. It may make sense to defer an unrequested operation for a short time. Everything else being equal, it's better to do all your networking continuously rather than powering the hardware on and off repeatedly. Be bursty if possible! But you should never stop the user from doing something based on Reachability.
  • Use Reachability to help diagnose why something failed. After trying to do networking, Reachability will tell you networking isn't available. This is valuable information that you can use to construct a good error message, and is probably more important than the exact error code that the API returned.
  • Allow the user to manually retry. The user might know that networking should work from this spot. Don't rely on iOS noticing that networking is now available and Reachability informing you. Again, the attempt could be the thing that makes it available.
  • Use Reachability's notification to automatically retry. When Reachability tells you the network is available, it's because it was available. It may go down again before you can finish your attempt, and it may be a captive network, but it's a good moment to try your request again.

You can see this behaviour in Mobile Safari. If a page fails to load, you're able to retry, regardless of whether the iPhone thinks you have a connection. If networking becomes available and Mobile Safari notices, though, it will try again automatically. It feels really natural.

Remember these guidelines:

  1. Mobile networking is not simple.
  2. The only sure way to determine if a network connection will succeed is to try it and see if it did succeed.
  3. Determining if a network connection actually succeeded isn't always trivial, either.

There's several WWDC 2011 sessions on mobile networking that are worth watching. (There are several from 2010 that addressed this, too, and I'm sure there will be several in WWDC 2012. It isn't a simple problem, and it isn't going away.)

Also: initWithContentsOfURL is synchronous. Don't use synchronous networking on iOS. If it takes an unexpectedly long time, your app will be quit by the iOS watchdog.

One advantage of Reachability is that it can send you a notification when the connection status changes. This way to you can inform your user that some functionality may be restricted.