使用可达性有什么好处?

使用可达性优于以下代码的优点是什么? 我觉得Reachability有大量的代码,但是如果以任何方式更好,那么我会使用它。

NSString *connectionString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]]; if ([connectionString length] == 0) { //No connection } 

现在被允许,如果谷歌曾经下跌,那么这是行不通的。 但是几乎没有发生这种情况的可能性。 你怎么看? 谢谢!

这实际上是一个很好的问题 – 我的公司正在招聘时,实际上在iOS开发人员访谈中使用它,

为什么苹果的可达性示例长达数百行,当你只用一行来检查一个URL是否有响应?

首先,networking可达性实际上是非常非常复杂的 。 这不仅仅是testing一个URL。 想想下面的例子:

  • 用户使用的是3G,但用完了数据许可,因此每个请求都会redirect到运营商的站点。

  • 用户连接到需要authentication/login的公共WiFinetworking,因此请求redirect到login页面

最后一个例子非常普遍 – 它总是发生。 但是,如果您使用initWithContentsOfURL您的应用程序会想象您具有连接性,但实际上您并不知道:您只会返回networking将您redirect到的页面内容。

这就是为什么苹果的代码比你想象的要复杂的原因之一。 你不应该只是问“我可以达到这个url” ,而是“从这个URL返回的数据是我所期望的 ”。

但这只是冰山一angular。 可达性除此之外还有更多的function – 例如,我可能有一个应用程序需要下载大量的信息,比如50MB。 如果用户在没有得到他们的同意的情况下使用3G连接(特别是在漫游的情况下),或者在受限制的数据计划中,那么简单地下载50MB数据将是一个糟糕的主意。 因此,可达性还会告诉你用户的连接types :EDGE,3G,WiFi等(注意:请参阅下面的注释,这可能不是最好的build议)。

Reachability里面的ReadMe.txt会告诉你一些关于代码可以做什么和不可以做什么的东西。

不幸的是,网上有太多的人没有意识到,有许多日常的情况下, initWithContentsOfURL将返回一个有效的响应,但用户不会有连接。 [像这样的博客文章] [1]在谷歌被索引,人们认为这是一个可以接受的替代品:不是!

我在招聘时问这个问题的原因之一是它可以显示开发人员不仅仅是在思考内部 – 像你和其他开发人员一样,当我看到Reachability示例代码的第一反应是“哇,这似乎太复杂了对于非常简单的事情“。 但希望这个答案会有一些方法来说服你,否则。


编辑:肯定注意下面的史蒂芬的评论。 他提出了我的答案没有考虑到的一些观点(即MiFi热点),并且提出了一个有效的例子:可达性不一定是它所编码的天堂的最高峰。 在许多情况下,开发人员将通过自己的改进等来修改Reachability。

可达性最大的问题不在于代码不好,要么代码不好。 这其实是相当不错的代码。 但是,很容易误解和误用的代码是为了达不到预期的目的。

以下是使用可达性的一些指导原则:

  • 是的,使用可达性。 也许最明显的一点是:可达性可以是一个巨大的资产,让你的应用程序感觉更自然。
  • 从不使用可达性作为预检检查。 仅仅因为Reachability报告networking目前不可用,并不意味着如果您尝试使用它,则无法使用 。 你没有发送的networking请求可能会唤醒iOS的networking。
    • 编辑:其实,我可能应该软化这一点。 推迟未经请求的操作可能是有意义的。 在其他方面相同的情况下,最好不断地进行所有的networking连接,而不是重复地开启和closures硬件。 如果可能的话,要突然! 但是,你永远不应该阻止用户根据可达性做一些事情。
  • 使用可达性来帮助诊断失败的原因。 尝试联网后,Reachability会告诉你networking不可用。 这是有价值的信息,您可以使用它来构造一个很好的错误消息,并且可能比API返回的确切错误代码更重要。
  • 允许用户手动重试。 用户可能知道networking应该从这个地方工作。 不要依赖iOS注意到networking现在可用,并且可以通知你。 再次,尝试可能是使它可用的东西。
  • 使用Reachability的通知自动重试。 当Reachability告诉你networking可用时,这是因为它是可用的。 它可能会再次下降,然后才能完成你的尝试,它可能是一个俘虏networking,但是现在是再次尝试您的请求的好时机。

您可以在Mobile Safari中看到此行为。 如果页面加载失败,则无论iPhone是否认为有连接,都可以重试。 如果networking变得可用并且Mobile Safari注意到,它将自动再次尝试。 这感觉真的很自然。

记住这些准则:

  1. 移动networking并不简单。
  2. 确定networking连接是否成功的唯一可靠的方法是尝试一下,看看它是否成功。
  3. 确定networking连接实际上是否成功并不总是微不足道的。

有几个关于移动networking的WWDC 2011会议值得关注。 (从2010年开始,也有几个也提到了这个问题,我相信在WWDC 2012中会有几个。这不是一个简单的问题,也不会消失。)

另外: initWithContentsOfURL是同步的。 不要在iOS上使用同步networking。 如果需要很长的时间,iOS应用程序将会退出您的应用程序。

可达性的一个好处是它可以在连接状态改变时向你发送通知。 通过这种方式,您可以通知用户某些function可能受到限制。

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

使用Reachibility的另一个很好的理由,除了@ lxt的很好的答案,就是如果你没有在你的应用程序中执行尽职调查来解决连接情况,你的应用程序将被拒绝。 苹果公司会testing你的应用程序是否有连通性,如果这两种情况都失败了,你的应用程序甚至不会被查看。

我完全同意lxt的回答。 它给你更多的连接细节,而不仅仅是“我可以连接到某个网站”。 伟大的问题。