How to create mock server response in iOS development with URLProtocol

Quang V. Ha
Nov 3 · 2 min read

One of the most common task in iOS app development is writing networking code. There’s a high chance that your team might also develop an own backend API and not always ready for you to do integration tests when you needed.

To make a fully functional demo app, you need to mock your server response. There are a couple workaround solutions for you as an iOS developer to do this:

  1. Use a 3rd party service like Postman
  2. write your own mock localhost server

Fortunately, you can mock the server response directly in your Swift/Objective-C code using URLProtocol provided by Apple.

URLProtocol declaration in Apple documentation

Your first MockURLProtocol

First of all, let’s create your MockURLProtocol class by inheriting open class URLProtocol :

requestHandler is where we will later pass our custom server response.

We need to override 4 functions as recommended by Apple:

  • canInit(with request: URLRequest) -> Bool
  • canonicalRequest(for request: URLRequest) -> URLRequest
  • stopLoading()
  • startLoading()

Integration

Next, instead of using URLSession.shared , initialize a URLSession with your custom URLSessionConfiguration :

let configuration = URLSessionConfiguration.ephemeralconfiguration.protocolClasses = [MockURLProtocol.self]let urlSession = URLSession(configuration: configuration)urlSession.dataTask(with: urlRequest) { data, response, error in
// ... handle your response
}.resume()

However, I suggest adding a Swift flag to easily fall back to original code:

Finally, passing your sample server response code provided by your backend team to requestHandler :

Customize your response

There are 2 main ways to customize your response:

  1. Handling request information such as:
MockURLProtocol.requestHandler = {request in // checking URL Path ...
if !request.url!.absoluteString.contains("/employeeInfo") {
// return 404 HTTPURLResponse
}
// checking headers ...
guard let v = request.allHTTPHeaderFields?["Authorization"] else {
return // or throw an error
}

2. Inherit MockURLProtocol , which is very useful if you create different class for different requests:

For example, if you had a class EmployeeInfoRequest , you just need to override startLoading function to pass your mock response. Then pass the new EmployeeInfoRequest.iMockURLProtocol class to -[URLSessionConfiguration protocolClasses]

You can apply polymorphism by using a protocol:


Further benefits

Beside supporting an iOS developer to make a functional app without a ready backend, mocking URLProtocol is actually really good for writing unit tests. Passing a mock response this way can help you check for:

  • whether your model matches your server response JSON
  • does your URLSession code already calls resume() ?

For more on related testing, please visit Apple’s WWDC18 talk: Testing tips and tricks

Quang V. Ha

Written by

Blogging is a great way of documentation, so I blogged about iOS development, some basics, some advanced,…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade