使用可达性有什么好处?
与下面的代码相比,使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这实际上是一个很好的问题 - 非常好,以至于我在公司招聘时在 iOS 开发者面试中使用了它:
首先,网络可达性实际上非常非常复杂。它不仅仅是测试 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:
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.
可到达性的最大问题不是它是糟糕的代码,也不是它是不好使用的代码。现在它实际上是相当不错的代码。但它的代码很容易被误解并误用于非预期目的。
以下是使用 Reachability 的一些准则:
您可以在 Mobile Safari 中看到此行为。如果页面加载失败,无论 iPhone 是否认为您有连接,您都可以重试。不过,如果网络可用并且 Mobile Safari 注意到,它会自动重试。感觉真的很自然。
请记住这些准则:
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:
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:
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.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.
所有的优点。我将补充:考虑使用 NSURLConnection。它有一个委托协议,可以通知您尝试建立连接时发生的所有相关事件/事件。与简单的 initWithCintentsOfURL 方法相比,它为您提供了更多的控制权,并允许异步处理。
但是,如果您从多个类中使用它,则多次实现所有委托方法可能会很麻烦。我将它包装在一个自定义类中,只有两个委托方法:didFail 和 didFinish,并在我的所有代码中重用该类。
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.
除了 @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.