Making http request without crying in Swift 5 😎 — Part 1
Well, to be here writting about swift seems to be a dream .. let me tell you the reason. My journey with swift has been poor and not so longer, but a few months ago receiving an oportunnity to work like mobile team teacher in a better job changed my plans. This job came with great ideas and projects to execute, so one of my first decisions was to use native development for an app. Stay React Native away was hard but the right choice for this project (As many friends know my background and almost all experience is JS Stack). The challenge was a great chance to show what I’m capable of .. However the project started and many things that I used to import, install, etc, were not available in Swift 😪. One of the biggest task that made me suffered searching and reading was making http request to rest services. I received a lot of errors not knowing why and neither how to sending params and queries. After all the effort and suffering I found a great library call alamofire to make better the job, so I will show you how to use it ✌.
Setup the project
Let’s open our Xcode and click in New Project…. The first thing to do is create App Project.
After that, we can choose a name for the project (whatever you think), I’ll use MakingRequest and most important is select “StoryBoard” as Interface, it’s better and easier this interface than SwiftUI for this project.
When our project is ready to work on it. We should be seeing something like this, we just use one View Controller to get this library work.
So, after that .. .We just put a small stack view in our view and inside the stack we’ll add a Label, Text View and a Button. We will not use styles for this example, just add the resources to the view and we start working on it. You’ll see something like this:
Finally to finish with UI, just link an outlet for every resource to the view, an action for the button and call them like you want.
To start with the good and pretty part of this post, we need to install alamofire. So, let’s create a pod file to have the ability to add a library. Just go to console, move to the root project directory and execute:
After we create the “Podfile” file, you can open it with the editor you prefer and add the library like this way:
If the image is not rendering in good quality, in the end of the file add:
You can put the version you prefer but if we put just Alamofire, we’ll receive the latest by default. Save and close your file and execute: “pod install”
So, finally we have a new file call .workspace. From now on, we will open the workspace not the xcodeproject.
Making GET Request
As you’ll se in Alamofire Documentation, the simplest way to make a HTTP Request is importing the library, getting an instance of AF and the method request which returns a response. Check this example that executes when the users clicks the button:
We are using this free API to make the example.
So, in just a few lines we’re doing a request … 🤓
The problem comes when you see the response in debug console:
WTF? A lot of data, wait … In the last part there’s something called body!
Yes! That body is the real data that wee need from the API. In this moment we can make request, get the data and see it. But this is not the rigth way to access to data, for example if we’d want to setup an array of movies, links or something, we are not capable of that in this moment.
We’re printing in debug mode, that’s why we see a lot of data, so next step is handling and customizing the response (Yes, we are not done 😭)
Customizing and handling the response
Like I said we have the response but not in the way we need …
¿what is the good way?
Firt’s of all, in Swift almost everything is about structs, so we will create two structs for managing the response. If we copy the URL that we are using to request data and put it in a new tab in our browser and go to. We’ll see the response from the API:
The browser shows us the response from the API and we can see four properties: userId, id, title and body. That’s why we need to create a “Model” with this data, create a new struct in the last part of your file (outside your view controller). Also we have now a model for the success data but missing a model for Errors, let’s create a generic model for errors (in a real example the backend team provides you the correct model of error in the API). Note that both structs are implementing Decodable and the second is using Error, because we need them to decoding data as the same type from the API. You should have two models:
Tip: If you see the data in the browser not the same like my example you can use this chrome extension to format your json:
Finally, the last and more important step. According to Alamofire documentation:
DownloadRequestboth have a corresponding response type:
DataResponse<Success, Failure: Error>and
DownloadResponse<Success, Failure: Error>. Both of these are composed of two generics: the serialized type and the error type. By default, all response values will produce the
AFErrorerror type (i.e.
DataResponse<Success, AFError>). Alamofire uses the simpler
AFDownloadResponse<Success>, in its public API, which always have
UploadRequest, a subclass of
DataRequest, uses the same
So instead of using the response handler by default, we can create or overwrite our own handler implementing the ResponseSerializer class of Alamofire. For this, we’ll use the second model we created, if the handler gets a success response we should return a custom model passed from the method that called us. But otherwise we return a APIErrorResponse instance, this part is import because you can change or create your custom handler depending of the responses from the backend. When I read this part in Alamofire documentation it was so difficult to manage a lot of concepts about catching the errors and returning the data that’s why I wrote a general version of this and I let it you below to implement it in the project. Just create a new swift file and call it “APIResponseSerializer”. Here it is the code.
To learn more about create or overwrite the serializer you can check it here.
Now, with our new and custom serializer we change this part in the code instead of use the default response we call .responseAPI and pass it the model of the success data you need, in this example we create the ResponsePost model to get the data and add a switch statement to evaluate the response. We can get a success data model or failure data model (APIErrorResponse), print the data and see the result:
We launch the app and click the button and …. magic 🤩🤩🤩!
Here it is, the response in a pretty way, we can handle it better. The new response serializer gave us a instance of our ResponsePost Model, so we can get the params we want:
Finally to finish this part, we’ll use the body param from the API response to change the data by default in our TextView. Just add this line after the print witch is setting the text value to the body from the response.
We reload the app, click the button and yeahh! That’s it! 👏👏👏
We can request data from an API, decoding the response and use the data to change the data in app.
Congrats 👀! You’ve learned to make http request in an easiest way with Alamofire and you can now use it to improve your swift app or change an old app with a lot of Network functions to this way.
- In next post we will make POST, PUT and DELETE request
- Ways to send data
- Headers and auth in API’s
✍ and post with ❤ by JimmyVazz