Get Instantly a Network Module using Moya in Swift

Omer Kolkanat
Trendyol Tech
Published in
3 min readMay 19, 2020

--

We create easily and quickly a network layer using Moya Framework with an example. I’m going to use the API of https://www.themoviedb.org to fetch data for the example. The example contains 3 methods of the API. These methods are popular movies, movie detail, and search.

Moya

Moya is a network abstraction layer. It uses Alamofire and provides us to set up a network manager quickly.

You can use Moya in your projects by adding required dependency. There are a few ways to install your project and you can get detailed information about the installation with this link.

API

After installation, 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 the required variables. We have baseURL, path, method, sampleData, task, and headers.

baseURL: The common prefix of the API URL.

path: The path after baseURL. We need to put dynamic value sometimes. For example, to fetch movie details we should put the movie id into the path like movie/{movieId}.

method: The HTTP method of request. It can be get, post, put, delete, connect, head, options, patch and trace.

sampleData: You can create a 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, but I explain common tasks. I used requestParameters for popular and movie type since api_key is required to pass as a query parameter.

We should use requestPlain if we don’t add any query parameter or body. To add query parameters for example: ?api_key=xxx. We should choose requestParameters. Also, we can use requestJSONEncodable for the body with an encodable request model.

header: The headers to be used in the request. When you need a header for the request, you can add headers into 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 generate response models quickly. I created MovieResponse, MovieDetailResponse and SearchResponse models. We can create NetworkManager.swift

We should define a protocol that contains provider and fetch methods. We should create a new class that extends the defined protocol. For this example, we have just 3 methods and a provider with an API file works for me. If you have to send many requests, the API file can be confused. You can create different API files like MovieAPI, LoginAPI, etc. and you can use different providers. Thus, it would be more organized.

Moya has a plugin that called as NetworkLoggerPlugin and it provides to log request and response into the console. I use the plugin to see the request and response logs. You can init the provider with the plugin.

I created a generic request method since inside of the fetch methods are the same except the response model and query. It prevents code duplication.

I 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 own error type like below and you can use it instead of Error.

enum NetworkError: Error {
case notFound
case unexpectedError
}

Making The Call

We should get an instance from NetworkManager to use the manager. I prefer to inject the Network Manager to class for testability. So, when we need to test the class we can easily create a mock network manager and inject it into the class.

private let networkManager: NetworkManagerinit(networkManager: NetworkManager = NetworkManager()) {          
self.networkManager = networkManager
}

If you don’t need to write a test you can get an instance like below:

private let networkManager = NetworkManager()

Now, we are ready to fetch the required data from the service.

You can find the example project link below:

I tried to explain how you can build quickly network module for your project. I hope it would be useful.

--

--