Stubbing requests using URLProtocol

A practical example of an API stub that works on Swift Playgrounds.

Yusuke Yamaguchi
Mar 19, 2019 · 4 min read

This is Yusuke Yamaguchi an iOS engineer.

The other day I boarded an escort ship named “Kaga” which was being publicly introduced at the Osaka port.

It was very surprising how everyone from WAVE (WAVE: A nickname given to the women in Japan’s Maritime Self-Defense Forces) was beautifully uniformed, but the most surprising thing was that washlets were attached to the ship’s lavatories. Moreover, the toilet seat foot stand was also attached, and the hand dryers were attached to the side of the hand wash as well.

I did not expect a ship’s installations to have evolved so far in the last 20 years.

Unfortunately, flushing the toilet itself still required the valve to be operated by me just like before… 😔

About the URLProtocol

Well, I think that in recent years most smartphone applications are assumed to interact with a server.

During the development of the application, the server will also probably be under construction. So, more often than not, we will employ mechanisms that return dummy responses.

There are various ways to return a dummy response, but in this article I’d like to show you an example of an implementation that uses the URLProtocol found inside the standard iOS SDK.

I think that it is pretty common to stub responses by using cloud services or implementing external libraries through CocoaPods and Carthage, but it is also possible to create stubs with just the standard SDK.

Since this functionality exists in the standard SDK, it can be freely used in Playgrounds.

This time I’ll present sample code that can actually be ran on Xcode 10.1 / Swift 4.2 / Playgrounds, but of course you can use Objective-C as well. (Since the Objective-C code will not be presented, please convert it accordingly.)

Overview of the URLProtocol class

Write a class that inherits from the URLProtocol class and override the necessary methods.

Returning true with `canInit(with:)` will instantiate it so that communication can be handled like a proxy server.

You can replace the actual communication processing at `startLoading`.

Since we are dealing with communication processing, there is a possibility that the process may be interrupted if you do not leave the Playground running, so write the following at the beginning:

Implement a class that inherits from the URLProtocol

At first, write the following code to activate the class.

Next, register the data you want to hook. (I will be using this structure so that I can group the definitions and easily look them over after.)

*Although it is omitted here, it is possible to toggle the hooks by adding a parameter.

Override the URLProtocol method

At first, override the class method `canInit(with:)`.

*If you are only logging network communications, you can output the log here and return false instead.

Then, override the methods that are required for using stubs.

Implementation of a container that defines the hook

This is the container that holds the previously registered hook definitions.

Describe the response of the stub

Since I also want to list the definitions of the JSON response, I will write them in a separate structure.

Make an HTTP Client

In this article we want to make everything work within Playgrounds, so I’ve made and HTTP Client myself.
Of course, for normal development you can use any library you want. (For example if you rather use .)

Bonus utility

When using `forEach` as it is, the execution might happen in parallel and end before we finish processing the transmission. This hinders the verification.

This has nothing to do with the main article itself, but defining it is useful as it will help us verify things that require an array of elements to be executed sequentially.

Use cases

Let’s see if two success patterns (notice and maintenance), one error pattern (error), and one without a hook definition (notfound) behave as expected.

Execution result

The stub for the response `notice` works 🍺

* hooked
* Response JSON(notice): ["notice": [["title": Notification 1., "code": 100], ["title": Notification 2., "code": 102]]]

The stub for the response `maintenance` works 🍺

* hooked
* Response JSON(maintenance): ["code": 100, "message": Now maintenance.]

The stub for the response `error` works 🍺

* hooked
* Response Error: Error Domain=test.api.error Code=1 "(null)"

If it doesn’t exists in the stub definitions, we expect it to NOT be handled, which also works. 😍

* Response Other: nil


What do you think?

You can make API stubs quite easily, even as a standalone.

By the way, if you create a new Playground with Xcode and paste all the code snippets presented in this article, everything should work, so please give it a try!

Thank you for reading.

*This article was released in Japanese at .

Stories by Fenrir Inc.

Tech articles and developer stories written by Fenrir's…

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.

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

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.

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