SCNetworkReachability / On-Demand Resources

Is it necessary to monitor reachability for on-demand resources? If so, what host address should be used? Thank you.

Replies

Is it necessary to monitor reachability for on-demand resources?

No.

I’m curious what prompted this question. How are you using reachability in other contexts?

In my experience reachability is one of the most overused API on our system. The API can be useful in some limited circumstances, but most folks end up using it for the wrong reasons, and that causes more problems than it solves.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

My interest in reachability is based upon two contexts within my application:


1. Determine if the server hosting the website associated with the application is available.

2. I anticipated that a likely error associated with beginAccessingResources would be NSURLErrorNotConnectedToInternet.


Thank you for your helpful reply.


Please allow me to refine my interest in reachability: Apple's On-Demand Resources Guide / Debugging On-Demand Resources / Networking Issues refers to the Reachability sample code and indicates this code can isolate common networking problems. The ReadMe.md in Reachability / Using the Sample mentions that www.apple.com is the default host and that this address can be changed. I wondered if it might be changed to an address associated with on-demand resources.


Perhaps I have misunderstood the documentation, but given the above, I'm under the impression that the Reachability code should be included in my application to identify networking errors for presentation to a user.

OK, just so we’re clear on the context, here’s the quote from the On-Demand Resources Guide:

Debugging networking issues is made easier with the Reachability sample code. It can check for network connectivity and the type of connection, and it can determine whether a specific host is reachable. You can use the information to isolate common networking problems. For example, if the host is reachable but the resources cannot be downloaded, either the app has the wrong URL for resources, or the host configuration has changed.

Other common network issues include the following:

  • The device is not connected to the network.

  • The device is connected to cellular, and the user has turned off data access for the app.

  • There is connectivity, but the server is not available.

  • The app is using self-hosted on-demand resources, and the URL for the content has changed.

Honestly, I have no idea what the author of that doc was angling at here. Are they recommending that you do this during development? Or for in-the-field diagnosis of problems? I read it as the former but you’ve interpreted it as the latter.

Regardless, I want to come back to something you wrote:

2. I anticipated that a likely error associated with

beginAccessingResources
would be
NSURLErrorNotConnectedToInternet
.

It sounds like you haven’t actually tested this. If so, my recommendation is that you try it and see what errors you actually get. This will inform how you should proceed with the error handling.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I am currently adding On-Demand Resources to one of our apps.


In the "Introducing On-Demand Resources" session (WWDC 2015) it was mentioned that beginAccessingResources would call the completion handler with a NSURLErrorNotConnectedToInternet error if there is no internet connection.


Unfortunately, this does not happen in my tests on iPhone with iOS 10.3.2. Instead, the completion handler is never called when the device cannot download the asset pack from the host.


I tried this both with asset packs hosted by Xcode and a TestFlight build:


I expected an error in the completion handler when the USB cable is not attached and the app is trying to download an on-demand resource from Xcode. Instead, the completion handler is never called.


With the TestFlight build, I tried two things: Airplane mode and using the Link Conditioner with 100% packet loss and then calling beginAccessingResources: in both cases, the completion handler is never called.


I'm currently considering adding

1) code that uses reachability to check if the internet is reachable before attempting to download an on-demand resource using beginAccessingResources

2) adding a cancel button to the progress screen - otherwise, the download screen is shown indefinitely since the completion handler is never called with an error


I tested this on an iPhone 6s and on an iPhone 6 with iOS 10.3.2.


This looks like a serious bug.

On-demand resources is not really my speciality but the behaviour you’ve described is inline with our standard policy for background downloads. In general we do not fail a download when networking is not available, but rather keep trying until either the request succeeds or some very long timeout expires (in the case of NSURLSession the default timeout is 7 days!).

I'm currently considering adding

1) code that uses reachability to check if the internet is reachable before attempting to download an on-demand resource using beginAccessingResources

Don’t do this. The problems with reachability are twofold:

  • It doesn’t actually help. The fact that the device has general Internet connectivity does not imply that it will be able to fetch your specific resource.

  • It can actively make things worse. There are circumstances where reachability might fail but your download might work, in which case gating your download on a reachability check is a bad thing.

2) adding a cancel button to the progress screen - otherwise, the download screen is shown indefinitely since the completion handler is never called with an error

You should definitely do that. Even if the resource download is working perfectly, it might be really slow, in which case the user might want to cancel anyway.

Finally, I want to stress that the approach I’ve outlined above is definitely Apple’s long-term direction. In fact, in iOS 11 we’ve added new API to NSURLSession standard sessions so that you can make them behave like background sessions in this regard. See the new

waitsForConnectivity
property and its discussion in WWDC 2017 Session 709 Advances in Networking, Part 2.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"