Using conditional conformances to improve API ergonomics in Flint

Development / iOS

My new open source framework Flint is pure Swift and involves splitting your code into small actions that when performed are passed a single input and a presenter object.

What is cool about this is that we use Swift’s associated types to allow action implementations to specify the type of the input and presenter. Here’s an example:

In the application, you perform the action via a generic type, the StaticActionBinding, using this function:

This all works great. Your binding has a perform(using:with:completion:) function that only supports the correct types the Action expects. However if you have an action that does not need an input or presenter, you have to use special types Flint defines called NoInput and NoPresenter to satisfy the associated types:

This works well enough, but invoking those actions would look like this:

It’s pretty ugly. Thanks to a nudge from @hishnash I looked into how we could eliminate the arguments that are not needed in those cases. I originally tried overloading the perform function with generic functions constrained on InputType and PresenterType but… you can’t do that.

It turns out that since Swift 4 the addition of conditional conformances can help us. We can overload the perform function and constrain each version to specific types for InputType and PresenterType:

(See full source: StaticActionBinding.swift)

Conditional conformances are only possible in extensions, and because the conditions vary for each version of the perform method we want, we needed three extensions as shown above.

However it is worth the effort. Invoking these kinds of actions is now much nicer:

That is pretty great. While generics and associated types can be a real pain to use, it’s important to celebrate these great little wins where something quite advanced is possible in a type-safe way with very little effort.

The Author

Marc Palmer (Twitter, Mastodon) is a consultant and software engineer specialising in Apple platforms. He currently works on the iOS team of Concepts sketching app, as well as his own apps like screenshot framing and backgrounds app Shareshot and video subtitling app Captionista. He created the Flint open source framework. He can also do a pretty good job of designing app products. You can find out more here.