From inspiration to production, Part 2

Christoffer Winterkvist
hyperoslo
Published in
5 min readMay 9, 2017

--

This is the second part in the From inspiration to production series.
The previous part touched on @hyperoslo’s core foundation and how it helped improve our process. This part goes into more detail on how we apply composition to build advanced yet maintainable applications.

Beauty in composition

composition
kɒmpəˈzɪʃ(ə)n/
noun: composition
a thing composed of various elements.

Composition as a pattern is nothing new, it has been around for some time. This is not about the concept itself but how use it to speed up development.

When we build applications we tend to not over-think the long-game.
What I mean by “long-game thinking” is that you try to think about all possible changes that might happen in the future. You start to analyze what could, should, would, possibly, maybe change going in the future. There is a more negative yet familiar term for this, pre-mature optimization. This is why we decided to go down a different path, using a foundation that infers composition in a declarative way. What this means in practice is that we tend to avoid having view related code directly coupled to the controller. Instead of having the controller own the responsibility of configuring all of its underlaying views, it is responsible for containing the views and laying them out linearly without knowing any underlaying implementation details of what is actually being displayed. By deciding on a linear layout from top to bottom and laying them out based on the size of the views, sprinkel a bit of voodoo magic to obtain continuous smooth scrolling while maintaining dequeuing, we can now change order and layout by defining different values on the component models. Less time spent discussing all possible futures is more time spent perfecting your implementation.

Aim high and challenge yourself

Doing a macOS application can be considered more challenging than iOS or tvOS. It has a set of unique challenges such as the window not having a constant size, the Y coordinate for a frame goes from bottom to the top. This can be solved by using auto layout. However, auto layout and dynamic content sizing does not always play well when you take into consideration that the user expects the window to resize as smooth as butter.

Take all these things into account, you could, depending on your familiarity with macOS, think that this design would be a daunting task. If you do consider it to be easy, I’d like to throw you a curveball. What if I told you that it should be highly dynamic and maintainable, would that change your initial thoughts?

Easier with linear factories

If you think about scrolling through a social media feed, reading a good book or parsing the contents of a file. What all of these practices have in common is that they are linear. It starts from top and moves down until it finally reaches the bottom. Applying the same idea when structuring your code can help you both reach flexibility and maintainability.

Why? Because it comes natural to us.

By sprinkling some declarative fairy-dust on your implementations, you are well on your way to write your own epic developer saga.

Now lets have a look at the code behind a subsection of the screenshot above.

What you see in this file is the same component models as you saw in the screenshot.

Because of its linearity it reads like an instruction manual that both you and the compiler are able to read. One thing that you’ll probably also notice is that none of the code in this class contains any platform specific code, nor does it use anything outside of Foundation.

I would argue that it is declarative enough for you to get a sense of what is gonna be displayed without having to run the application, this might or might not be true.

Adding new components is as easy as adding a new model at the index of your preference. Tinkering with the model kind will change the user interaction for the component user interface. Adjusting the layout parameters can give the component a unique look and feel, or follow the existing user interface convention for the application.

All this from just changing model code. It helps you iterate faster but it also gives you fine-grained control that would otherwise usually result in refactoring controller specific code.

When you write a book, you don’t write it for yourself

So far I’ve been mentioning the upsides of this kind of architectural choices for you as a developer, but it also adds a lot of value to the product, your developer and non-developer co-workers. You are now on track to building an implementation that can tackle UI change, experimentation, designer collaboration and A/B testing with less effort than if your layout was tied to the feature you were working on. This saves you time and transforms you from being a “That will be a non-trivial task” to “Yeah let’s try it out to see how it looks and feels”. The beauty of this is that you spend your time building views instead of controller specific UI logic, because lets face it, the users can see your views but never your logic. And in this day and age, appearances matter.

Simple on the inside, awesome on the outside.

At @hyperoslo, we have found that this way of working is fast enough to use for customer application prototypes. The ultimate difference between prototyping this in native code in comparison to using Framer, Invision or any other tool, is that you give yourself an incredible head start as all the views that you build can be used in the final product. You also get the opportunity to easily add the prototype, err…correction, early version of the application, on the customers phone which is something that makes a huge difference when having an open relationship with your clients.

To summarize, by making it simplistic through convention, you can have a clear focus on what you want to achieve with your application. It opens up for more collaboration which is essential for any good application. Don’t think too much about the future, it will always be unknown, just make sure that you can easily adapt to it. Prototype in code, why? Because everything else has the potential to skew expectations.

This is the end of the second part in the From inspiration to production series. In the next part, we will continue to dive even deeper into what we have learned along the way. It involves taking an homage too far, type aliases, protocol extensions and preprocessors statements.

You can find me on Twitter @zenangst and on GitHub @zenangst.

--

--

Christoffer Winterkvist
hyperoslo

random hero at @fink-oslo by day, cocoa vigilante by night, dad at dawn. my life is awesome. Previously @hyperoslo