简体   繁体   English

使用Reachability有什么好处?

[英]What is the advantage of using Reachability?

What is the advantage of the using Reachability over the code below? 使用Reachability比下面的代码有什么好处? I feel that Reachability has a huge amount of code, but if it's better in any way, then I'd use that instead. 我觉得Reachability有很多代码,但如果它以任何方式更好,那么我会用它代替。

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! 谢谢!

This is actually quite a good question - so good that I actually use it in iOS developer interviews when my company is recruiting: 这实际上是一个非常好的问题 - 我在公司招聘时在iOS开发人员访谈中实际使用它是如此之好:

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? 为什么Apple的可达性示例数百行,当您只需使用一行来检查URL是否响应时?

Firstly, network reachability is actually very, very complicated . 首先,网络可达性实际上非常非常复杂 It's much more than simply testing for a URL. 它不仅仅是测试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. 用户使用3G,但已用完了数据限额,因此每个请求都会重定向到运营商的网站。

  • The user is connected to a public WiFi network that requires authentication / login, so the request redirects to a log in page 用户连接到需要身份验证/登录的公共WiFi网络,因此请求会重定向到登录页面

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. 但是如果您使用initWithContentsOfURL您的应用程序会想象您有连接,而实际上您没有:您只需返回网络重定向到的页面内容。

This is one reason why Apple's code is more complex than you might at first think it needs to be. 这就是为什么Apple的代码比你最初想象的要复杂得多的原因之一。 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 ". 您不应该只是问“我可以访问此URL” ,而是“从此URL返回的数据是我期望的 ”。

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

The ReadMe.txt inside Reachability will tell you a little more about what the code can and can't do. Reachability中的ReadMe.txt将告诉您更多关于代码可以做什么和不可以做什么的内容。

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. 遗憾的是,网上有太多人没有意识到有很多日常场景,其中initWithContentsOfURL将返回有效的响应,但用户将无法连接。 [Blog posts like this][1] get indexed in Google, and people assume it's an acceptable substitute: it's not! [博客这样的帖子] [1]在Google中被编入索引,人们认为它是可接受的替代品:它不是!

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". 我在招聘时提出这个问题的原因之一是,它可以显示开发人员不只是在盒子里思考 - 就像你和许多其他开发人员一样,当我看到Reachability示例代码时我的第一反应是“哇,这看起来太复杂了对于非常简单的事情“。 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 (ie, MiFi hotspots), and makes a valid case that Reachability isn't necessarily the peak of coding heaven it code be. 他提出了我的答案未考虑的一些要点(即MiFi热点),并提出了一个有效的案例,即Reachability不一定是编码天堂代码的顶峰。 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. 是的,使用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 . 仅仅因为Reachability报告网络当前不可用并不意味着如果您尝试使用它将无法使用它 That network request you're not sending could be the very thing that wakes up iOS's networking. 您没有发送的网络请求可能会唤醒iOS的网络。
    • 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. 但是你永远不应该阻止用户根据Reachability做某事。
  • Use Reachability to help diagnose why something failed. 使用可达性来帮助诊断出现故障的原因。 After trying to do networking, Reachability will tell you networking isn't available. 尝试建立网络后,Reachability会告诉您网络不可用。 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. 这是可用于构造良好错误消息的有用信息,可能比API返回的确切错误代码更重要。
  • 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. 不要依赖iOS注意到现在可以使用网络,并且可通过Reachability通知您。 Again, the attempt could be the thing that makes it available. 同样,尝试可能是让它可用的东西。
  • Use Reachability's notification to automatically retry. 使用Reachability的通知自动重试。 When Reachability tells you the network is available, it's because it was available. 当Reachability告诉您网络可用时,这是因为它可用。 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. 您可以在Mobile Safari中看到此行为。 If a page fails to load, you're able to retry, regardless of whether the iPhone thinks you have a connection. 如果页面加载失败,无论iPhone是否认为您有连接,您都可以重试。 If networking becomes available and Mobile Safari notices, though, it will try again automatically. 如果网络可用且Mobile Safari注意到,它将自动重试。 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. 有几个关于移动网络的WWDC 2011会议值得关注。 (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.) (2010年有几个也解决了这个问题,我相信WWDC 2012会有几个。这不是一个简单的问题,它不会消失。)

Also: initWithContentsOfURL is synchronous. 另外: initWithContentsOfURL是同步的。 Don't use synchronous networking on iOS. 不要在iOS上使用同步网络。 If it takes an unexpectedly long time, your app will be quit by the iOS watchdog. 如果需要很长时间,iOS应用程序将退出您的应用程序。

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. 这种方式可以通知您的用户可能会限制某些功能。

All good points. 所有的好处。 I will add: consider using NSURLConnection. 我将补充:考虑使用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. 它为您提供了更多的控制,即一个简单的initWithCintentsOfURL方法,并允许异步处理。 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. 我将它包装在一个只有两个委托方法的自定义类中: didFaildidFinish ,并在我的所有代码中重用该类。

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

I agree wholeheartedly with lxt's answer. 我全心全意地同意lxt的回答。 It gives you a lot more detail in your connectivity than just "can I connect to some website". 它为您提供了更多关于连接的详细信息,而不仅仅是“我可以连接到某个网站”。 Great question. 好问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM