mikeash.com pyblog/friday-qa-2013-06-14-reachability.html commentshttp://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsmikeash.com Recent CommentsThu, 28 Mar 2024 09:38:43 GMTPyRSS2Gen-1.0.0http://blogs.law.harvard.edu/tech/rssOleg - 2014-06-30 09:51:16http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsWhat bothers me is the potential race condition that can occur when I call SCNetworkReachabilityGetFlags in a helper thread, while the SCNetworkReachabilityScheduleWithRunLoop has already been set in the main run loop. <br /> <br />There are going to be two different threads both checking for network reachability at the same time and returning their result to the main thread. If network status changes somewhere in between, the events may appear in the run loop queue in an incorrect order. <br /> <br />Is there a way to guarantee the correct event order? Ideally, to make the SCNetworkReachabilityScheduleWithRunLoop to trigger events upon request (not only upon actual network status change)db4d87f651fe400cb61e90bdd9fddbf6Mon, 30 Jun 2014 09:51:16 GMTZav - 2013-08-22 14:19:48http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsVlad, your link is no longer valid: <br /> <br /><a href="http://developer.apple.com/library/ios/#qa/qa1693/_index.html">http://developer.apple.com/library/ios/#qa/qa1693/_index.html</a> <br /> <br />This link works though (remove the # in the URL): <br /> <br /><a href="https://developer.apple.com/library/ios/qa/qa1693/_index.html">https://developer.apple.com/library/ios/qa/qa1693/_index.html</a> <br /> <br />Here is a related link with more info that Apple also recommends: <br /> <br /><a href="https://developer.apple.com/library/ios/technotes/tn2277/_index.html">https://developer.apple.com/library/ios/technotes/tn2277/_index.html</a>ccec5e9df24567cf5928fb39dfa637c3Thu, 22 Aug 2013 14:19:48 GMTGreg Combs - 2013-07-09 16:29:12http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsVlad is absolutely spot-on. When your connectivity is on the fringes of reachability, SCNetworkReachabilityGetFlags() will definitely put a damper on user-experience. The best way I know to approach this is to make sure your code actually only calls GetFlags once (but not on the main thread) and then monitor that address for reachability, reusing the flags that you get back. <br /> <br />I've seen a ton of folks on GitHub use reachability helpers that call GetFlags any time they check if a host is online (even if it's one that they've previously checked on).b5f3b6c660c9b066938540833f5aec32Tue, 09 Jul 2013 16:29:12 GMTKonstantin - 2013-06-21 18:47:30http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsSteven is right, the Internet is way more complicated than reachability API suggests. The server you're trying to connect to may be reachable from the point of view of TCP/IP, but not actually respond (web server/backend problems). The server may appear unreachable because of access points' authentication, firewalls, cell company restrictions, weird VPN setups and what not, but will respond when you ask it. <br /> <br />The only real way to check it is to make a request using <i>the</i> protocol you normally use, including the necessary authentication parameters if any. Reachability API is just a quick and dirty test for trivial connectivity issues. It can provide useful information, but you cannot trust it as a one-stop solution, even for diagnostic purposes.26f651775244698eb4e150f0a1d544efFri, 21 Jun 2013 18:47:30 GMTNolan - 2013-06-17 15:05:22http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsI think Steven's point is very valid and nobody should be gating code based on reachability. However, gating UI is another issue. Apple themselves use reachability to update their app's UI such that if there is not network (per reachability) they block UI in apps that require an internet connect - however behind the scenes, the app is still making network requests as normal. This shows the usefulness of providing users feedback based on reachability without relying on in for you application's logic. Look at Apple's iTunes and Apple Store apps for examples of this.9d73e2f200863276485f69042b199d58Mon, 17 Jun 2013 15:05:22 GMTDavid Dancy - 2013-06-17 04:50:16http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsI'm using Reachability to determine when to switch on/off some extra functionality in my app. The app has features that only apply when connected to a special web server, and I depend on Reachability to tell me whether the server is available so I can go ahead and switch them on. If I used the "try first, then diagnose failure" method, it seems to me that I'd have to implement some kind of polling which would waste the battery. The special web server isn't often available so Reachability seems like as good a trigger as any to determine when an attempt at talking to the special web server would be worthwhile. (Of course I also handle failures in actual transmissions, but that's a separate issue in my case). I admit that allowing the user to initiate the conversation with the special web server would also work, but it's not part of the design for the app. <br />One frustration I have though is that I can't find a way (yet - still scouring the docs) to <i>force</i> a network communication to use the Cellular radio instead of WiFi. The idea is to be connected on local WiFi to my special web server, but still able to talk over the Cell connection to other web connections. Normally I'd allow the OS to determine how to do this, but sometimes the WiFi is pre-configured in Infrastructure mode and NSURLConnection isn't clever enough to work out what's going on. I can detect the configuration using Reachability flags (I think) but I can't get around it to force other traffic onto the Cell-based internet connection. Is this even possible?64b3b59c9e15f98495887c2357c248c0Mon, 17 Jun 2013 04:50:16 GMTPierre Lebeaupin - 2013-06-16 12:54:50http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsIn support of Steven Fisher, I think I do remember reading or hearing at WWDC to indeed only query Reachability after a first attempt that failed, because Reachability not only reports false positive but false negatives as well, though I can't exactly remember what those false negatives were. It's kind of like filesystem accesses: I try, then handle failure. <br /> <br />But on top of failure reason and when to reattempt connection, I also used Reachability to know whether the particular access I was doing (reading a video) was being done cellular or WiFi, not for internal decisions as this is not reliable enough, but for user information: this may be different from what's shown in the status bar as that may show WiFi, but that WiFi is actually a private network and my app is actually using cellular. <br /> <br />Also, I don't know if it is related, but if the network issue is deep in the ISP network Reachability won't be able to tell you when access is back, so it is still necessary to allow the user to manually retry.04db8152c77f59cb9392cc71f2f32a8dSun, 16 Jun 2013 12:54:50 GMTVlad - 2013-06-15 13:36:59http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsThere is a thing about SCNetworkReachabilityGetFlags() that I think it worth mentioning: if reachabilityRef is not scheduled in a run loop then SCNetworkReachabilityGetFlags will operate in synchronous mode, blocking current run loop until it determines the reachability of host. If the run loop is main loop (which is usually the case) then there is a risk of watchdog killing your app. <br />This is similar like doing [NSData dataWithContentsOfURL:] and other related and seemingly innocent methods. While this is not clearly explained in SCNetworkReachability Reference it is better described in <a href="http://developer.apple.com/library/ios/#qa/qa1693/_index.html">http://developer.apple.com/library/ios/#qa/qa1693/_index.html</a> .01934371770591edbe0d9c336cad494cSat, 15 Jun 2013 13:36:59 GMTRoger - 2013-06-15 00:20:23http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsMy pet peeve is being unable to find out if the user is roaming. There are circumstances where I don't want to do networking even if things are reachable.a86c4c081fb72867a2566dc587e0f4c2Sat, 15 Jun 2013 00:20:23 GMTSteven Fisher - 2013-06-14 18:44:33http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsBasically, I use Reachability in two ways: <br /> <br />1. I use it to provide more guidance on why my connection failed after it fails. At this point, I know that I'm as close to a connection as I can be. And Reachability can help me answer "So why didn't it work?" <br />2. I use it to determine when I should retry. When Reachability says the network is up, it was definitely (at that moment, anyway) up.0f8e4aff597f94408c3954ab2baa16d2Fri, 14 Jun 2013 18:44:33 GMTSteven Fisher - 2013-06-14 18:41:14http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsReachability tells you that networking is connected. You may be disconnected due to being in a lower power state. If only you tried, the networking would power up and you'd be connected.a99a9d1812e83a11bff65b2474496493Fri, 14 Jun 2013 18:41:14 GMTChris L - 2013-06-14 16:05:47http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsI know Apple has always recommended that you try making a network request first, and only check reachability if and when it fails. So this is what I always do, though I haven't personally run into a situation where it wouldn't work the other way. (Perhaps VPN on demand, or some other situation where the network isn't up until you request something.) <br /> <br />Also it's grounds for app store rejection if your app fails but doesn't tell the user they need a network connection to continue. <br /> <br />Cheers36c45c3ad2e711cf423dfe7429e33f25Fri, 14 Jun 2013 16:05:47 GMTRobert Vojta - 2013-06-14 16:01:18http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsBasically, networking is much more complicated than this simple reachability tool. Sometimes it takes lot of time to set up route/path (especially in cellular networks, …) and reachability can fail. As Steven wrote, reachability is nice, but you can't take it too seriously - I mean, you can't depend on it and stop trying. There also can be firewall/router/... rules where reachability can fail and request succeeds, etc.0a92392c126da6f6f461217298395c1aFri, 14 Jun 2013 16:01:18 GMTmikeash - 2013-06-14 15:10:37http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsCan you elaborate on that? When would reachability say "no" when a request would work?f6a508f60907d9aacffe331b7499db8cFri, 14 Jun 2013 15:10:37 GMTSteven Fisher - 2013-06-14 14:55:24http://www.mikeash.com/?page=pyblog/friday-qa-2013-06-14-reachability.html#commentsI think you're way off on this one. Reachability is great for diagnostic purposes, but you should never use it before making a request. <br /> <br />Watch for the network to come online and then, sure. But make sure you try that first time. <br /> <br />i run into apps all the time that gate on Reachability, and it just doesn't work. <br /> <br />There was a WWDC session in 2011 about this.a73d576180a1a8fdc39e832cdcd5e3b9Fri, 14 Jun 2013 14:55:24 GMT