1

When I try to start a basic NSURLSession transfer while the network is offline (air plane mode), with NSURLSessionConfiguration defaultSessionConfiguration and ephemeralSessionConfiguration, I of course immediately receive the NSError :
Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline."
But with NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier, the NSURLSession never returns, no response in any way, no timeout fired, it get stucked.
This happens with iOS 8.x. With iOS 7.x, I got the NSError as expected.
Why that ? Is there a way to get some error back ?

  • Hmm. One of the key features of background sessions is that it won't try to initiate the connection until the remote server is reachable. Is it possible that you just check reachability before initiating the request? – Rob Jun 16 '15 at 16:43
  • Yes, of course, I know I could use Apple Reachability sample code, to check the reachability before initiating the request. But I didn't knew background sessions don't try to initiate connection while offline. By the way, if I start the background transfer with a reachable network, and then I cut the network off, the session gets sucked too. If I reconnect to the network again, the transfer resumes. – user3048615 Jun 16 '15 at 17:07
  • WWDC 2014 [What's New in Foundation Networking](https://developer.apple.com/videos/wwdc/2014/?id=707) discusses this feature of background sessions. Regarding timeout behavior in iOS 7 v iOS 8, see http://stackoverflow.com/q/26379449/1271826. – Rob Jun 16 '15 at 17:31
  • @Rob I dont think it would be a good idea to use reachability to determine if the original request should be sent. It has been widely discussed at [github](https://github.com/AFNetworking/AFNetworking/pull/2704/files). – Utsav Dusad Mar 11 '16 at 14:10
  • @utsavdusad - In general, that's right: A governing design principle is that it is often better to try something and let it fail, rather than checking if it could succeed before trying. This is why that README says what it does. But the OP's scenario is different: a background session _won't_ trigger an error, so if you want to see if the network is available or not, then you have to check. – Rob Mar 11 '16 at 16:18
  • @Rob - I agree with you but I have some concerns about reachability being not accurate. "If Reachability says the server is unreachable, you're supposed to try anyway. Because even though Reachability says it won't work, it will often be wrong about that and it will work. This is how unreliable networking is: Even the indication that it's not available might be wrong." Source: [Github discussion](https://github.com/AFNetworking/AFNetworking/issues/2701) – Utsav Dusad Mar 11 '16 at 16:36
  • Yes, I agree. Reachability is ideal for showing the user some visual indication re the status of the network, not for testing whether the network request is guaranteed to succeed. – Rob Mar 11 '16 at 17:22

1 Answers1

3

In general, an NSURLSession background session does not fail a task if something goes wrong on the wire. Rather, it continues looking for a good time to run the request and retries at that time. This continues until the resource timeout expires (that is, the value of the timeoutIntervalForResource property in the NSURLSessionConfiguration object you use to create the session). The current default for that value is one week! In other words, the behaviour of failing for a timeout in iOS7 was incorrect. In the context of a background session, it is more interesting to not fail immediately because of network problems. So since iOS8, NSURLSession task continues even if it encounters timeouts and network loss. It continues however until timeoutIntervalForResource is reached.

So basically timeoutIntervalForRequest won't work in Background session but timeoutIntervalForResource will.

I got this answer from one of the members of Apple Staff at the developer forum. Also, I have verified this by implementing.

Utsav Dusad
  • 2,139
  • 4
  • 31
  • 52