From inspiration to production, Part 4

Christoffer Winterkvist
hyperoslo
Published in
8 min readJan 7, 2018

--

This is the fourth and final part in the From inspiration to production series.

Why we still believe in Native.

First of, what do we mean when we say “native”? We mean sticking with Apple’s tooling, building applications with either Swift or Objective-C. All the alternatives that we have looked at so far market themselves with either being easy to use, target developers from other platforms or the plain old cross-platform argument. All these things are great, they sound great and they absolutely have value. What they don’t seem to address is the cost. A lot of companies have jumped on React Native, and again, for good reasons. We totally understand and respect that as a choice, but it is not our choice. Mainly because a lot of the applications that we see are sub-par, they feel lacking in one way, shape or form. There are also companies that do terrific things with the alternative tooling built by the community. We don’t want to be in the first category of developers and our strengths up to this point all reside in the native corner. Saying that native development is hard is as valid as saying some other thing is hard just because you haven’t mastered it. Native is far from perfect and it takes time to master, heck we haven’t mastered it yet, few have. But we have the collective knowledge to be able to build first class applications. Any new obstacle that we run into with native development is almost always something that we can overcome and the payoff when you finally get it is tremendously gratifying, especially if you share that experience with someone else. Hence our frameworks being wrappers around already existing Apple technology, adding an additional level of abstraction to unify the way we build applications. The main difference being that we built the abstraction, not another company with different needs.

Don’t become a victim of business decisions purely based on numbers. I know that you probably don’t have the mandate to make these kind of decisions, but any good company should be willing to listen to good arguments and make a better decision. Remember that there are no silver bullets, each technology has their set of pros and cons.

Not a silver bullet

If you think about composition as a tool, you wouldn’t use a hammer when performing open hard surgery, here you would certainly favor something with a bit more finesse and tailored for the task.

We still do custom implementations where we need to do things the “old fashioned” way. Why? Because Spots and composition as a pattern is not a silver bullet nor is it meant to be. Our implementation revolves heavily on reusable views with dequeuing, these things don’t play well with frameworks that are heavy on the hardware, e.g. SpriteKit or MapKit. But knowing that there is an alternative pattern for building 70–80% of your app faster than you would normally do gives some comfort in a developer world where compile cycles are tediously long and there is a long road ahead before things will be where we want them to be.

When these custom implementations occur, we tend to evaluate if this custom client implementation can be turned into a framework. This is a good perspective to have if you intend to work on open source during work hours. Ask yourself, could this be reused? Will this need appear again for another client? If both questions result in ’yes’, then you know what you should do.

We don’t aim to compete

We never sought out to compete with other frameworks that seek to solve the same problem. Instead we wanted something that addressed our day-to-day needs. We believe that there can be simultaneous innovation when it comes to doing UI development based on composition and what better way to get this up on Apple’s radar then by doing our own take on it. The “worst” that could happen is that we, the people of strive forward in composition-land, get Sherlocked at the next WWDC which in my own opinion wouldn’t be a bad thing.

Initially, our focus point revolved heavily around constructing UI from JSON. This never restricted us in any way but the real world value of it has been spares at best. Not to say that it won’t change in the future. Instead of scrapping that idea, we decided to stick with it and use it on an internal level.

One feature to heavily rely on the JSON to UI computation is the live reloading feature. We needed a way to change the current state of a screen without having to run the application again. This was accomplished by saving the current view state to disk in JSON form. What we didn’t realize at the moment was that we had effectively created a view state cache that greatly reduces the need for any database in the application.

API driven apps seldom have a specific need to store everything in Core Data or Realm, people just tend to do it via convention. The two latest apps that we have shipped does not have a database at all, instead we rely on cache keys for the view controllers which means that it will save the content to disk using the cache key as a MD5 generated file name and when ever you make a new instance of the controller using that cache key it would get the components from disk and render it as soon as the view controller is presented.

When the view controller reaches out to the endpoint (if this were and API based application) it would then reload with new components using our very well used reloadIfNeeded function that handles component model diffing for you, constructing targeted updates in the most appropriate way possible from the frameworks perspective. If items change on a component, it would either insert, update or delete them. If entire components change, it will either create new ones, replace existing once or just soft update them, calling the methods that cause the least amount of strain on the device. The same works for update items, if a specific item changes but it does not modify the size of the item, it would be considered a soft update. If the height changes it would cause for a targeted update that would tell the current index path to reload, the same would occur if you were to change what type of view you would like to display. Doing it this way reduces the amount of potential blinking that can occur when you reload reusable collections or tables because it creates new instances of the view that was reloaded. All and all, we end up with a better user experience with less code in our client applications.

We started with one feature that we thought was important but it ended up opening doors to other more important ones that we found down the line.

I know it might seem odd to list a lot of our features when the title for the this segment is that we don’t aim to compete. It is mainly there to show you that setting out to fix your pains can lead to better features that tailored to you instead of looking at others for your way forward. It is also there to show that we didn’t have a great big scheme to create these features when we started. They naturally occurred during development. A sort of “ops-we-created-something-great-development”. But don’t leave everything up to change, having a north star is something that we do encourage.

Be inspired but follow your own path.

So why open source?

With all the advantages that this brings to the table, why would we share our foundation and frameworks with our competitors? We don’t see the world as black and white. We might work for different companies but open source gives us an arena to be co-workers. Wouldn’t you rather look at a world filled with potential than to look at and think, “if we do this people will just copy what we do and we will lose our edge”. You will never lose your edge from sharing what you do, remember, you are still you and even if the competition is following in your footsteps based of what you do share, they will do just that, follow.

At Hyper, we do a great deal of open source and we wouldn’t have it any other way.

Spots + Injection = ❤️

Something that made its way into my workflow a while back was Injection for Xcode. For those who don’t know what it is, it is a way to inject source code into your application so that you don’t have to recompile to see the changes. Initially written as an Xcode plugin, which hit a huge speed bump with the release of Xcode 8 as plugins could no longer be used without un-signing your installation. Injection saw a new light when the developer decided to rewrite his implementation into a standalone application that resides in your menu bar.

Working with injection can be tricky as you have to structure your code in a specific way for it to work. When building views you want to ensure that the current controller that you are working with is getting a brand new instance of the view that you inject. By accident, Spots ended up tailored to this task as you can reload your entire view controller with a set of component models, this will enforce that you get new instances, and this is done with one line of code inside your injection method.

controller.reload( controller.components.map { $0.model } )

What this does is that it will take the current model structure for the controller and simply make new components and display them on screen.
If you are making your own framework and would like it to play well with Injection, it could help a lot to take this into account. For us it happened by accident but it doesn’t have to for you.

http://injectionforxcode.com

Personally I highly recommend using Injection, it has certainly done wonders to my workflow but a word of caution. The future of injection could be limited as Apple has already broken some of the nifty features that Injection for Xcode provides, such as running injection on the device. This broke with the introduction of iOS 10. I hope the future of injection is bright but I wouldn’t be shocked if Apple took a final stab and killed it entirely. I dread the day that would happen, so enjoy it while you can.

Summary

So to summarize what this four part article was about, and what it was not about.

It is not about selling you a framework but to share knowledge from what we learned from when we built a framework.

Discuss things, it is important that you and your team are on the same page, no matter the size of the team.

It is nearly impossible to get it right the first time, perfection through iteration is much easier to achieve.

It is better to try and fail than to not try at all.

Aim high and be in it for the longrun, I’m sure that you’ll end up going through quiet an epic adventure if you just see it through.

It is okay to make mistakes, we all do. It’s what we learn from them that counts.

Preprocessors statements, protocol extensions and type aliases can be fantastic tools but a heartache when overused.

Document your implementations, your co-workers will love you for it.

Do open source, remember that you were once a beginner, let’s make our community a better place.

Write articles, share what you know, not just for everyone else but also for yourself. If you write it down, there is a higher chance that you’ll remember it later. Future you will high five past you if you do.

Give composition a run for its money, maybe it’s not for you but at least you tried it out and now know that it’s not for you.

This is the end of fourth part in the From inspiration to production series, thank for reading.

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