Haven’t played Monster Hunter tri, but visually this was my favourite

@propertyWrapper is fun

Suraj Sau
3 min readAug 8, 2020

While I was going through on how to make HTTP calls in Swift with Alamofire and subsequent URLSession tutorials, the HTTP calls looked something like,

While Alamofire does a pretty impressive job in cutting down a lot of the boilerplate, I soon realised that for projects with a lot many HTTP calls, maintenance of the API functions could be a lot easier if the generation of the Request URL and processing of response in completionHandler are separated.

Being an Android developer, I’m very used to how Retrofit (Android’s goto Networking Library) lets us separate the HTTP call URL generation and underneath calling of functions from the responseListener. Something like,

interface are nothing but protocol and each function represents the entirety of an HTTP call. All you need to do is call the function which will return an Observable of the Response. Neat and simple right.
What Retrofit in Kotlin/Java does under the hood is that, for each of the function annotated with @GET or @POST, the compiler synthesises all the required boilerplate to convert them into full-fledged HTTP calls with callbacks.

I was wondering if something like this could be done in Swift too and then I struck gold when I came across@propertyWrapper in Swift. The official documentation it reads,

A property wrapper adds a layer of separation between code that manages how a property is stored and the code that defines a property.

For example, if we wanted to have String fields to always return value in the “CamelCased” format, we can write a @propertyWrapper as follows,

PS: This isn’t the most optimised solution

The parallel I could draw in Kotlin would be either the custom getters and setters or even better, Property Delegates. In Kotlin, the above example would look something like this,

PS: This isn’t the most optimised solution

Using @propertyWrapper we would try achieving a Retrofit-like syntax for our Alamofire boilerplates. Something like,

Let’s begin by typealiasing our completionHandler closure to Observer<T>.

Next, let us implement a GET struct as a @propertyWrapper.

So what is going on here,
1. we have a local variable url which is being set at init.

2. the calculated value wrappedValue is of type Observer<T> which is going to behave as our completionHandler from wherever we make the HTTP call.

3. inside the get we return a closure where the entire Alamofire boilerplate resides. So, every time I fetch the variable which has been tagged with this @GET propertyWrapper, all I’ve deal it is the completionHandler in the closure without worrying of the underneath HTTP call boilerplate.

So now, we can ‘declare’ our HTTP calls and use them with minimal code as follows,

So…

Though this example showed the implementation of a wrapper @GET(:url)is a small portion of all the possible types of HTTP calls. The main reason for me to write this up was to demonstrate how @propertyWrapper can be used to do a lot of heavy lifting to make our code more readable and manageable in the long run.

I’m still very new to iOS and working my way through it. So, if you have any suggestions or corrections feel free to reach me on Twitter or let me know in the comments below.

Also, I love reading about Monster Hunter and the vast foray of ecological varieties it provides. I’ve started maintaining a personal collection of ecology and lores from various sources I come across. Interested people do give it look 🐲

--

--

Suraj Sau

Android Developer. 日本語勉強中。한국어를 공부하고.