Handling Network calls in Swift with Moya
It’s a powerful network tool that meets your needs!
Moya is a Swift network library built on top of Alamofire. It makes network calls without directly communicating with Alamofire. It is focused on making network requests in a type-safe way by using enumerations (e.g., enum
).
Why Moya?
You’re a smart developer and probably use Alamofire to abstract away access to URLSession
all those nasty details you don't really care about. But then, like lots of smart developers also write ad hoc network abstraction layers. They are probably referred to as APIManager or NetworkModel, and they always end up crying.
How to fix this?
Moya provides us with an abstraction to make network calls without directly communicating with Alamofire and focus on your application's core features instead of networking in no time.
Ad hoc network layers are commonly found in iOS apps.. They’re bad for a few reasons:
- It is difficult to write new apps (“how to begin?”)
- It’s hard to sustain existing applications (“oh my God, this mess…”)
- Makes it hard to write unit tests (“how do I do this again?”)
So Moya’s fundamental idea is that we want a network abstraction layer that sufficiently calls Alamofire directly. This will make common tasks easy while still providing enough functionality so complex requests can be handled easily.
Features of Moya:
- Compile-time checking for correct API endpoint accesses.
- Let's define a clear usage of different endpoints with associated enum values.
- Provide a Swift-first API/abstraction for making network requests.
- Provide an API to help stub network queries.
- Provide basics of response decoding.
- Favor explicitly-defined behavior over default implementations.
Installation
You can integrate Moya into a project using CocoaPods, Carthage, or the Swift Package Manager.
Use this link for the installation https://github.com/Moya/Moya#installation
Tip: Always specify library versions when installing dependencies. For example, if you are using Cocoapods, target a specific version number for your project!
pod ‘Moya’, ‘15.0’ # latest version at the time of writing.
API Manager
After installing the pod, we should create an API.swift file and create an enum that includes different requests. We should extend the API enum with Moya’s TargetType and conform to the required variables. There is baseURL, path, method, sampleData, task, and headers.
Target Type Protocol
Now that you have created your API enum with all your endpoints listed, we need to import Moya and adhere to the Target Type Protocol. Let’s discuss the above code snippet in detail,
baseURL: Every target (e.g., a service) requires a base URL. Moya will use this to eventually build the correct Endpoint
object.
path: The path after baseURL. We need to put dynamic value sometimes. For example, to fetch movie details we should put the user id into the path like user/{userId}.
method: The HTTP method of request. It can be get, post, put, delete, connect, head, options, patch, and trace.
sampleData: You can create mock/stub data for the response for testing. If you don’t write any test, you can return empty data like in the code.
task: Represents an HTTP task. It contains several tasks, here let’s discuss few common tasks. You’re expected to return aTask
enumeration case for every endpoint you want to use. There are many ways you can request information, such as a plain request, data request, or parameters request. You also have the option to upload files or upload request, and many more. We used requestPlain to get User Details because the request does not require any additional data, here is a simple get request,
We should use requestParameters when we want to pass parameters and define our own type of encoding. (look at the example below).
header: The headers to be used in the request. When you need a header for the request, you can add headers to the dictionary.
Network Manager
We need to create response models for mapping. I use https://app.quicktype.io to generate a response model from a JSON response. I recommend this tool to create quick response models. I created a User model.
Here is a User. swift model and We used Codable for parsing JSON into the Model.
We can create a NetworkManager.swift file for declaring all the APIs that we are going to use.
We should create a new class that extends the defined protocol. For this example, we have just 2 methods and a provider with an API file works for me. If you need to send multiple requests, the API file may get confused. You can create different API files like UserAPI, LoginAPI, etc. and you can use different providers. Thus, it would be more organized.
Moya has a plugin called as NetworkLoggerPlugin and it provides to log requests and responses into the console. We have used the plug-in to view the request and response logs.
We created two generic request methods fetchUsers() and fetchUserDetail(). Both the methods are the same except for the response model, and query, & it also prevents code duplication.
We used Result
type that came with Swift 5.Result
type is implemented as an enum that has two cases: success
and failure.
You can also create your own error type.
Making The API Call
We can get an instance from NetworkManager to use the manager.
We have created an object of NetworkManager and an array of Users.
Now, just call the API and fetch the required data from the service and display it.
Conclusion
- Making use of Moya for networking and Codable for parsing JSON responses is easy, but as your API grows in size, so your networking classes grow up with it, too, as does the amount of code you need to write. To make the code more manageable and easier to maintain, we used inheritance and generalization when necessary.
- We extracted the
BaseService
protocol to be used by all our API definition enums and implemented its common properties as an extension. - For the network part, we retrieved the
BaseNetwork
class which handles errors, validates successful responses, and converts response bodies using generic methods.
Hope you enjoyed the read. Maybe I convinced you to try out Moya in your next project. What do you prefer using a network library or coding one yourself? 🤔 Please, share your thoughts in the comments.
Please click here for the demo.
Until next time, stay tuned and keep following Simform Engineering for more such important and exciting blogs on latest tools and technologies.