iosdev

Alley, automatic retries for any URLSessionDataTask

It’s not yet another networking library.

On my perpetual path of removing the oft-repeated boilerplate from each project I tackle, I’ve built a really small wrapper around URLSessionDataTask to implement one feature that’s always requested at some point: automatic request retries.

It’s called Alley and I encourage you to just take Alley folder and copy it into your project. Then adjust as you see fit.

In most cases where you need to fetch something from the internet, you:

  1. Want to get the data at the URL you are targeting, no matter what.
  2. In case when it’s simply not possible, display some useful error to the end-customer and display / log what error actually happened so you can troubleshoot and debug.

Second point is merely nice to have, although a very nice to have. First one though, that’s the main deal: that data is the reason you are performing this request at all. So in just about any client project, automatic retry appears as task to do at some point.

The main design goal of this wrapper: do not reinvent URLSession. I have no desire to write (nor use) yet another network library where you need to setup a bunch of stuff or re-factor your networking code in order to make use of it.

I assume that you would already have some URLSession instance to handle URLRequests. Then instead of this:

let urlRequest = URLRequest(...)

urlSession.dataTask(with: urlRequest) {
	data, urlResponse, error in
	//...process error, response, data
}

task.resume()

with Alley you will do this:

let urlRequest = URLRequest(...)

urlSession.perform(urlRequest, maxRetries: 5) {
	dataResult in
	//...process dataResult
}

That closure with dataResult will be called after up to 5 attempts were made to execute the URLRequest. In the current version retries will happen if URLSessionDataTask returns one of these URLError instances:

I plan to update this list as I find new appropriate cases for it.

If maxRetries argument is not sent, it will fallback to default value of 10, declared on URLSession as static property maximumNumberOfRetries.

The README for the repository provides detailed explanation for DataResult and NetworkError types, thus I won’t repeat that here.

Core of the functionality is just one file, which adds some useful methods to URLSession. The only one you will use is the perform() mentioned above. Internally, it’s pretty straightforward:

perform → authenticate → execute → (process) → validate

and then either return to caller by executing the Callback provided in perform() or go back to authenticate to try again.

authenticate method seems superfluous and strangely named but I did it on purpose to make a suggestion where you can hook-up OAuth2 or some other authorization.

Alley is really simple but ready to build complete web API client libraries by simply extending what’s already there.

It’s not at 1.0 yet because I want to test it a bit more, refine if needed and maybe see if I can make it usable as Swift Package or Carthage or CocoaPods. Although I’ll probably never use it in such a way – I’ve built it with the same concept in mind as Fields form-building library: a solid foundation for concrete implementation of service wrappers.