使用可达性有什么好处?

发布于 2024-12-01 14:14:28 字数 347 浏览 2 评论 0原文

与下面的代码相比,使用 Reachability 有什么优势?我觉得 Reachability 有大量代码,但如果它在任何方面更好,那么我会使用它。

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

if ([connectionString length] == 0) {

    //No connection

}

现在理所当然,如果谷歌宕机了,那么这个方法就行不通了。但实际上这种情况不可能发生。你怎么认为?谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

人海汹涌 2024-12-08 14:14:28

这实际上是一个很好的问题 - 非常好,以至于我在公司招聘时在 iOS 开发者面试中使用了它:

为什么 Apple 的可达性示例长达数百行,而您只需使用一行即可检查 URL 是否响应?

首先,网络可达性实际上非常非常复杂。它不仅仅是测试 URL。考虑以下示例:

  • 用户使用 3G,但已用完数据限额,因此每个
    请求重定向到运营商的网站。

  • 用户已连接到公共 WiFi 网络,需要
    身份验证/登录,因此请求重定向到登录页面

最后一个示例非常常见 - 这种情况经常发生。但是,如果您使用 initWithContentsOfURL,您的应用程序会认为您具有连接性,但实际上您没有:您只会返回网络将您重定向到的页面内容。

这就是为什么苹果的代码比你一开始想象的更复杂的原因之一。您不应该只是问“我可以访问此 URL”,而是“从该 URL 返回的数据是否是我期望的数据”。

但这实际上只是冰山一角。除此之外,可达性还有更多作用 - 例如,我可能有一个应用程序需要下载大量信息,例如 50MB 的信息。如果用户在未经同意的情况下使用 3G 连接(尤其是在漫游或使用受限数据套餐时),那么简单地下载 50MB 数据将是一个坏主意。因此,可达性还会告诉您用户使用的连接类型:EDGE、3G、WiFi 等(*注意:请参阅下面的注释,这可能不是最好的建议)。

Reachability 中的 ReadMe.txt 会告诉您更多有关代码可以做什么和不能做什么的信息。

不幸的是,有太多在线用户没有意识到,在许多日常场景中,initWithContentsOfURL 将返回有效响应,但用户不会连接。 [像这样的博客文章][1]在谷歌中被索引,人们认为它是一个可接受的替代品:事实并非如此!

我在招聘时问这个问题的原因之一是,它可以表明开发人员不仅仅是在框内思考 - 就像您和许多其他开发人员一样,当我看到 Reachability 示例代码时,我的第一反应是“哇,这似乎太复杂了对于一些非常简单的事情”。但希望这个答案能够在某种程度上让你信服。


编辑:一定要注意下面史蒂文的评论。他提出了一些我的答案没有考虑到的观点(即 MiFi 热点),并提出了一个有效的案例,即可达性不一定是编码天堂的巅峰。在许多情况下,开发人员会通过自己的改进等来修改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 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.

就像说晚安 2024-12-08 14:14:28

可到达性的最大问题不是它是糟糕的代码,也不是它是不好使用的代码。现在它实际上是相当不错的代码。但它的代码很容易被误解并误用于非预期目的。

以下是使用 Reachability 的一些准则:

  • 是的,使用 Reachability。也许是最明显的一点:Reachability 可以成为让您的应用感觉更自然的巨大资产。
  • 切勿将 Reachability 用作飞行前检查。仅仅因为 Reachability 报告网络当前不可用,并不意味着它不会变得可用如果您尝试使用它。。您未发送的网络请求可能正是唤醒 iOS 网络的东西。
    • 编辑:实际上,我可能应该软化一点。暂时推迟未请求的操作可能是有意义的。在其他条件相同的情况下,最好连续进行所有网络连接,而不是反复打开和关闭硬件电源。如果可以的话就爆发吧!但您不应该永远阻止用户执行基于可达性的操作。
  • 使用 Reachability 帮助诊断失败的原因。尝试建立网络后,Reachability 会告诉您网络不可用。这是有价值的信息,您可以使用它来构建良好的错误消息,并且可能比 API 返回的确切错误代码更重要。
  • 允许用户手动重试。用户可能知道网络应该从这里开始工作。不要依赖 iOS 来通知网络现已可用以及可达性通知您。再说一次,尝试可能是让它变得可用的原因。
  • 使用 Reachability 的通知自动重试。当 Reachability 告诉您网络可用时,这是因为它可用。在您完成尝试之前,它可能会再次出现故障,并且它可能是一个强制网络,但现在是再次尝试您的请求的好时机。

您可以在 Mobile Safari 中看到此行为。如果页面加载失败,无论 iPhone 是否认为您有连接,您都可以重试。不过,如果网络可用并且 Mobile Safari 注意到,它会自动重试。感觉真的很自然。

请记住这些准则:

  1. 移动网络并不简单。
  2. 确定网络连接是否成功的唯一可靠方法是尝试并查看是否成功。
  3. 确定网络连接是否真正成功也并不总是那么简单。

WWDC 2011 有几场关于移动网络的会议值得关注。 (2010 年也有几个解决了这个问题,我相信 WWDC 2012 中也会有几个。这不是一个简单的问题,而且不会消失。)

另外:initWithContentsOfURL 是同步的。不要在 iOS 上使用同步网络。如果花费的时间超出预期,您的应用程序将被 iOS 看门狗退出。

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.

无名指的心愿 2024-12-08 14:14:28

Reachability 的优点之一是它可以在连接状态发生变化时向您发送通知。通过这种方式,您可以通知您的用户某些功能可能受到限制。

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.

我ぃ本無心為│何有愛 2024-12-08 14:14:28

所有的优点。我将补充:考虑使用 NSURLConnection。它有一个委托协议,可以通知您尝试建立连接时发生的所有相关事件/事件。与简单的 initWithCintentsOfURL 方法相比,它为您提供了更多的控制权,并允许异步处理。
但是,如果您从多个类中使用它,则多次实现所有委托方法可能会很麻烦。我将它包装在一个自定义类中,只有两个委托方法:didFaildidFinish,并在我的所有代码中重用该类。

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.

没有伤那来痛 2024-12-08 14:14:28

除了 @lxt 的精彩答案之外,使用 Reachibility 的另一个很好的理由是,如果您没有在应用程序内执行尽职调查来考虑连接场景,您的应用程序将被拒绝。 Apple 会在有连接和无连接的情况下测试您的应用程序,如果其中任何一种情况失败,您的应用程序甚至都不会被查看。

我完全同意lxt的回答。它为您提供了更多有关连接的详细信息,而不仅仅是“我可以连接到某个网站吗”。很好的问题。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文