Getting Started with Moya

Malcolm Kumwenda
Feb 8, 2018 · 10 min read
Image for post
Image for post

Moya is a Swift Network Abstraction Library. It provides us with an abstraction to make network calls without directly communicating with Alamofire. With this tutorial we will learn how to get started with the framework, discover some tips & tricks and learn all basics from code examples.

Why Moya?

Let’s firstly discuss why NOT Moya:

  1. It introduces a dependency to your project. Your project’s success is partially determined by Moya’s stability.
  2. There are way more reasons why you would NOT want to use Moya but they are all derived side effects of point number one. You should always consider the cost of adding a dependency to any project. For a more in-depth analysis on why it’s better to build your own API manager from scratch in Swift, please do yourself a favor and read this great article by Matteo Manferdini.

When I first started using Cocoapods I thought found some developer superpowers. I eventually realized that it is more important to understand how things are achieved rather than having super code from a library. This is how you improve your skills as a developer. Behind Moya is NOT some black magic code that communicates with servers and returns JSON!

Why you WOULD Moya:

  1. Set up an API Manager in no time.
  2. Clean code and best practices.
  3. Focus on your applications core features instead of networking.
  4. Easy to stub network responses for unit tests.
  5. Learn how to use a popular Swift networking library. Have you ever seen “Experience with REST API’s using best practice and well-known libraries” on a job post? I definitely have.

There are many benefits to using Moya these and others included, but this does not mean that writing a Network Layer in pure Swift is difficult or not desirable.

Set-by-step Guide


Moya can be installed using your preferred means of installing dependencies:

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’, ‘10.0.1’ # latest version at the time of writing.


Before you get to building your Network manager I would advise some design and planning beforehand! Yes, I know, as developers we just want to get to the code. But taking some time to plan our work would be a worthy investment.

So what should I plan to build a network manager? Not that much! Let’s keep it simple and down to two questions. I always begin my planning with questions which I need to provide the answers:

  1. Which endpoints will I be requesting data from?
  2. How will I model the data returned from the endpoints?

When answering these two questions I just simply make a list of all the endpoints in notes and create pseudocode models from the expected JSON. If you are working with an already documented API you can use the documentation provided as the reference. I will make use of The Movie Database API 🍿 for most of the examples.


Thanks to Swift 4’s Codable protocol we don’t have use any object mapping libraries or write custom mappers to convert our JSON to a model. Let’s build our Movie Model, MovieResults Model.

Movie Model

If we make a request to The Movie Database API to get playing movies, the returned JSON response looks like this. From this JSON we want to model two objects MovieResults and Movie. We will make use of these two structs to model our JSON response.

Image for post
Image for post
Movie Model.

Things to note:

  • When the name of the variable you are using is different to the one the API provides you need to implement a CodingKey enum. It tells Swift exactly how to map your JSON.

MovieResults Model

Similar to the Movie Model we need to conform to the Decodable protocol.

Image for post
Image for post
Movie Results Model.

Things to note:

  • Here we see that Decodable can even map arrays of objects for us.

API Enum

Create an enum to house all your endPoints. Each case should take the parameters you want to pass to that specific endPoint.

Image for post
Image for post
The last two cases are only for example purposes.

Things to note:

  • Create a case for each endPoint.
  • When you have an endPoint that requires a lot of parameters, your case can get very long and ugly. You can keep things clean by passing a dictionary:
// First import Alamofire to make use of ‘Parameters’
case endPointWithLotsOfParams(parameters: Parameters)

Let’s get to real work!

We will look at the Target Type Protocol, building a Network Manager, Dependency Injection and Plugins.

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. Moya’s Target Type protocol consists of 7 properties: baseUrl, path, method, sampleData, task, validate, header.


Let’s make our MovieApi enum conform to the TargetType protocol.

Image for post
Image for post

We use enums to switch between different environments. This is a neat way of providing the functionality to switch between environment. Make sure, that this property is a static constant as you don’t want your application to switch environments on the fly. I would suggest having such configurations tied to a Xcode build configuration instead of in code.


The root of our URL.

Image for post
Image for post
URL breakdown.

The red is our baseURL followed by the version of the API. So will be our baseURL. There are instances where we can have multiple environments such as QA, Staging and Production with a different baseURL. Let’s see how we can cater for both situations.

Image for post
Image for post
Basic baseURL with no environments.

When we have one baseURL it is straightforward. Create an URL with the string to the baseURL and return a URL. URL(string: String) returns an optional URL so we unwrap the value and throw an error if we get a nil. Let’s look at a configuration that handles multiple environments.

Image for post
Image for post
Multiple environment configurations.

Create a Swift file named NetworkManager. Then create an enum that will have a case for each environment we could have. Next make a struct that will have our provider and a static instance of the environment.

Things to note:

  • Our Network Manager is a struct which is a value type.
  • We keep our provider private as we do not want anyone outside of this file to access the provider directly.


The path is best described in Moya’s own code. By pressing ‘Option’ followed by a click on the path property and Xcode will present you with a popover.

Image for post
Image for post
Description of the path variable.


The type of HTTP request method to use for a particular endPoint. Moya provides us with all the HTTP request methods that we would need to perform all CRUD operations.

Sometimes, all you will need to use is the GET method. In this case there is no need to switch on Self. Do not use a switch-case when not necessary. You can just return get.

Image for post
Image for post
Using API only to retrieve data.

When you do perform other methods a switch on self is required. Make sure that you provide the right method for each request. Sending a delete request to a getter method on the API you will be presented with beautiful errors and unexpected behavior.

Image for post
Image for post
Using an API with various requests.


  • Use Moya.Method as sometimes Xcode cannot find the Method namespace.


Image for post
Image for post

For the purpose of providing data for your tests. When writing Unit Tests your application should never communicate with the API. You need to test your application in isolation. This is why you need to provide a sampleData. I personally like to keep my production code and testing code separate so I create a separate file for my sampleData and also create separate JSON files for each endPoint.

Inside the MovieAPI+Testing I will have my sampleData and a method that returns the JSON data from the JSON files in our StubbedResponses group.

Image for post
Image for post

Creating stubbed response from our JSON files.


To create a JSON file in Xcode just CMD+N then select empty file and name it adding “.json” at the end.


Different API’s expect data to be given to them in different ways. The task property is where you handle this. Parameters in each task can be sent in various ways.

Image for post
Image for post
Moya Request Types
  1. requestPlain — Used when the request does not require any additional data. For example a simple get request.
  2. requestData — Used when the request expects data to be passed in the body of the request.
  3. requestJSONEncodableUsed when the request expects a JSON encodable object whereas no.2 expects Data.
  4. requestParameters Used when you want to pass parameters and define your own type of encoding. (Look at example below)
  5. requestCompositeDataUsed for when you want to pass Data as the request body and also pass urlParameters at the same time.
  6. requestCompositeParametersSame as no.5 but takes parameters instead.
  7. downloadParametersAs the name suggests used to download and also pass parameters if needed.
  8. uploadCompositeMultipart Used to upload multipart with parameters.
Image for post
Image for post


This property is used by Alamofire to validate responses. It is by default set to false so responses won’t be validated. You can use it to validate whether the response you are getting matches what is expected in your headers. Validate is also used to confirm the response status codes. For more on this you can look at this 👈or even👉 that.


Every request that you make via HTTP has headers. For more information on headers read this article.

Image for post
Image for post
Simple HTTP headers.

Network Manager

We need to create a Networkable protocol. This protocol defines all properties and methods that you require your manager have.

Image for post
Image for post
Networkable Protocol

Creating your NetworkManager. As the Moya documentation suggests make use of a struct for your Manager.

Image for post
Image for post
NetworkManager with getMovies call.


  • Moya has a request method that returns a progress block. Using this property plus a progress view you can easily implement a nice loader into your application.

Dependency Injection

Many times when developers write a network layer they expose it to their ViewController by using a singleton class that they can access everywhere. This was once a bad practice that even I partook in. The problem with this approach is that your code becomes tightly coupled to the Network Manager and almost untestable. Singletons are very hard to test, trust me I have tried. So how do you get your Network Manager into your ViewController? Dependency Injection! We simply create a Network Manager instance and pass it to ViewControllers that need it.

Image for post
Image for post

Here we create a provider and pass it to our MainViewController. The MainViewController needs a provider (it depends on the provider) so we give (inject) an instance of the network provider.

Image for post
Image for post

When having such an implementation you have complete control over the NetworkManager object that is injected. Making the code less coupled and much easier to test!

Things to note:

  • We pass an object of type Networkable. This way we can pass in any object that implements this protocol.
  • By using Networkable we can easily create mocks and pass them into this class.


Moya comes already with some nifty plugins that you can use. I like making use of the networkLoggerPlugin which simply logs all network activity to the console as it happens.

let provider = MoyaProvider<MovieApi>(plugins: [NetworkLoggerPlugin(verbose: true)])

Change your provider instantiation so that it looks like the one above and your application’s network traffic will be logged to the console. There are other plugins that you can add to your provider. You can even write your own custom plugins. More on plugins here.


In summary using Moya boils down to creating an enum that conforms to the TargetType protocol. It is amazing what the combination of Swift enums and protocol oriented programming can achieve. With this implementation we have a clean well defined network layer that any new developer can read and understand at a glance.

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.

Some random fun fact:
Moya happens to mean ‘Spirit’ in Zulu which is one of South Africa’s 11 official languages.


Moya’s official Github page.

Flawless iOS

🍏 Community around iOS development, mobile design, and…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store