What is the advantage of using Reachability?

2020-05-13 16:53发布

What is the advantage of the using Reachability over the code below? I feel that Reachability has a huge amount of code, but if it's better in any way, then I'd use that instead.

NSString *connectionString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];

if ([connectionString length] == 0) {

    //No connection

}

Now granted, if Google ever went down then this wouldn't work. But there's literally no chance of that happening. What do you think? Thanks!

5条回答
手持菜刀,她持情操
2楼-- · 2020-05-13 17:32

All good points. I will add: consider using NSURLConnection. It has a delegate protocol that informs you of all relevant events/incidents that happen when trying to establish a connection. It gives you much more control that a simple initWithCintentsOfURL method, and allows for asynchronous processing. But if you use it from many classes, it may get cumbersome to implement all the delegate methods many times. I wrapped it in a custom class with only two delegate methods: didFail and didFinish, and reuse that class throughout all my code.

查看更多
成全新的幸福
3楼-- · 2020-05-13 17:35

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.

查看更多
女痞
4楼-- · 2020-05-13 17:36

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.

查看更多
The star\"
5楼-- · 2020-05-13 17:38

Another good reason to use Reachibility, in addition to @lxt's great answer, is that if you are not performing your due diligence inside your app to account for connectivity scenarios, your app will get rejected. Apple will test your app with and without connectivity, and if it fails either of those scenarios, your app won't even get looked at.

I agree wholeheartedly with lxt's answer. It gives you a lot more detail in your connectivity than just "can I connect to some website". Great question.

查看更多
▲ chillily
6楼-- · 2020-05-13 17:47

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 every request redirects to the carrier's site.

  • The user is connected to a public WiFi network that requires authentication / 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.

查看更多
登录 后发表回答