使用Reachability有什么好处?

时间:2011-08-24 15:43:28

标签: iphone objective-c ios ipad ipod

使用Reachability比下面的代码有什么好处?我觉得Reachability拥有大量的代码,但如果它以任何方式更好,那么我就会使用它。

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

if ([connectionString length] == 0) {

    //No connection

}

现在已经获准,如果Google失败了,那么这将无效。但实际上没有机会发生这种情况。你怎么看?谢谢!

5 个答案:

答案 0 :(得分:45)

这实际上是一个非常好的问题 - 当我的公司招聘时,我实际上在iOS开发人员访谈中使用它:

  

为什么Apple的可达性示例有数百行,当你可以使用一行检查URL是否有响应时?

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

  • 用户使用的是3G,但已经用尽了他们的数据限额 请求重定向到运营商的网站。

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

最后一个例子是非常普遍 - 它一直在发生。但如果您使用initWithContentsOfURL您的应用程序会想象您有连接,而实际上您没有:您只需返回网络重定向到的页面内容。

这就是为什么Apple的代码比你最初想象的要复杂得多的原因之一。您不应只是问“我可以访问此网址”,但“是从此网址返回的数据,我希望它是”。

但这真的只是冰山一角。除此之外,可达性还有很多 - 例如,我可能有一个需要下载大量信息的应用程序,比如50MB。如果用户在未经他们同意的情况下使用3G连接,那么简单地下载50MB数据将是一个坏主意 - 特别是如果他们正在漫游,或者是在受限制的数据计划上。所以Reachability还会告诉你用户所处的连接类型:EDGE,3G,WiFi等(*注意:请参阅下面的注释,这可能不是最好的建议)。

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

不幸的是,网上有太多人没有意识到有很多日常场景initWithContentsOfURL会返回有效的响应,但用户不会有连接。 [博客这样的帖子] [1]在Google中被编入索引,人们认为它是可接受的替代品:它不是!

我在招聘时提出这个问题的原因之一就是它可以显示开发人员不只是在盒子里思考 - 就像你和许多其他开发人员一样,当我看到Reachability示例代码时我的第一反应是“哇,这似乎对于非常简单的事情来说太复杂了“。但希望这个答案会在某种程度上说服你。


编辑:请务必留意下面史蒂文的评论。他提出了我的答案没有考虑的一些要点(即MiFi热点),并提出了一个有效的案例,即可达性不一定是代码所在的编码天堂的顶峰。在许多情况下,开发人员将使用自己的改进等修改可达性。

答案 1 :(得分:29)

可达性最大的问题不在于它是不好的代码,还是使用它的代码不好。它现在实际上是相当不错的代码。但是,为了达不到目的而误解和误用是很容易的代码。

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

  • 是的,使用可访问性。也许最明显的一点是:可访问性对于让您的应用感觉更自然非常重要。
  • 永远不要将可访问性用作预检检查。仅因为可访问性报告网络当前不可用并不意味着它不可用如果你试着用它。您没有发送的网络请求可能会唤醒iOS的网络。
    • 编辑:实际上,我可能应该稍微软化一下。在短时间内推迟未请求的操作可能是有意义的。在其他条件相同的情况下,最好连续进行所有联网,而不是反复打开和关闭硬件。如果可能的话就要破裂!但是你应该从不阻止用户根据可达性做某事。
  • 使用可访问性来帮助诊断出现故障的原因。尝试进行网络连接后,可访问性将告诉您网络不可用。这是可用于构造良好错误消息的有用信息,可能比API返回的确切错误代码更重要。
  • 允许用户手动重试。用户可能知道网络应该在此位置工作。不要依赖iOS注意到现在可以使用网络,并且可通过Reachability通知您。同样,尝试可能是让它可用的东西。
  • 使用Reachability的通知自动重试。当Reachability告诉您网络可用时,这是因为它可用。它可能会在你完成你的尝试之前再次下降,它可能是一个专属网络,但现在是再次尝试你的请求的好时机。

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

请记住以下准则:

  1. 移动网络并不简单。
  2. 确定网络连接是否成功的唯一可靠方法是尝试并查看是否成功。
  3. 确定网络连接是否实际成功并非总是微不足道。
  4. 有几个关于移动网络的WWDC 2011会议值得关注。 (2010年有几个也解决了这个问题,我相信WWDC 2012会有几个问题。这不是一个简单的问题,也不会消失。)

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

答案 2 :(得分:4)

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

答案 3 :(得分:3)

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

答案 4 :(得分:2)

除了@ lxt的最佳答案之外,使用可访问性的另一个好理由是,如果您未在应用内部执行尽职调查以考虑连接方案,则您的应用将被拒绝。 Apple将测试您的应用程序是否有连接,如果它在这些情况下失败,您的应用程序甚至都不会被查看。

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