1

Problem

I'm currently grabbing weather forecast information with [NSData dataWithContentsOfURL: url]. The problem with this is that if there are errors during the URL fetch, I just get back a nil.

An alternative to the method [NSData dataWithContentsOfURL:options:error:] will provide error info to me, but what my calling function wants is the data, not a possible error that it must diagnose and deal with.

Requirements

What I'd like is a single function that a client can call to grab a URL that "absolutely will not stop" until the URL has been loaded.

I don't want the function's clients to need to think about:

  • Timeouts.
  • Internet connections being unavailable or not.
  • The device being locked or the app moving in to the background.
  • The actual site in question being down.
  • Other sources of error.

Other design objectives

  • The function should treat the device and remote site nicely – it should not swamp it with requests resends that will certainly fail, for example.

  • The caller should be able to abort the attempt if it desires, so it'll want to have a handle to the request allowing it to kill it off.

  • The function should be asynchronous, taking a block to handle the result when it eventually arrives.

  • For extra marks a method for the calling function to be sent error diagnostics would be nice. Again, I think a block would work nicely for this. The needn't do anything about the error, because the function isn't going to give up, but it can use it to provide useful feedback to a user. For example, to allay their concerns, or prompt them to take remedial action (turn networking back on, for example).

Possible interface

So the a client call to the function might go like this:

_currentGrabber = [TenaciousURLGrabber 
  grabberForURL: myURL
  withCompletionAndDiagnosticsHandler: 
    ^(NSData* finalData, ErrorObject *error){
      if(data)
      {
        // Update my UI using data.
      }
      else
      {
        // Update my UI to show `[error localisedError];`
      }
    }];

If the client gets bored or decides that the fetch isn't worth it any more, it can do:

[_currentGrabber invalidate];

Implementation thoughts.

It'd be great if this pretty much already exists. Otherwise, I'm interested in suggestions on implementing this functionality.

I should probably be making use of NSURLSession instead of the older NSURLConnection. The possibility of background (out of process) downloads looks useful? Any tips beyond this?

The function should use SCNetworkReachability as demonstrated in the Reachability sample application following failure to determine when its worth a retry attempt.

Community
  • 1
  • 1
Benjohn
  • 13,228
  • 9
  • 65
  • 127
  • What have you tried so far? Please share code of what you have tried? Also I think this would probably generate opinion based answers on different ways people would say is the best way answers shouldn't be opinion based so maybe reword your question to sound less opinion based. Also I do have to ask what was with the original title of `A "Terminator T-800" URL Fetch...`? What was with the terminator part? – Popeye Aug 28 '14 at 08:00
  • :-) I'm currently using `[NSData dataWithContentsOfURL: url]`, which has no apparent retry behaviour. I'm about work on a better solution. I'd prefer to apply that to another problem if there is an _obvious known solution_ that already exists, or heed other's experience in developing a viable solution. "Terminator" – you know, right, _The Terminator_? "It absolutely will not stop"? No? You're right, it's probably not a great tittle :-) – Benjohn Aug 28 '14 at 09:09
  • Oh ok I like how you tried to add a bit of humor to your title :) Could you update your question with the code that you have tried please, I think your question is good it just lacks the code you have tried already that's all. – Popeye Aug 28 '14 at 09:22
  • Fair enough :-) Done – let's see if that helps. I'm off to do some shopping. – Benjohn Aug 28 '14 at 11:11

0 Answers0