my coding adventures

In this tutorial I’m going to explain how to build an App of the Day card in Swift using GridLayout.GridLayout is a Swift library for displaying UI elements in a grid like structure. GridLayout is available on GitHub.

In this article, I’m going to explore several Swift mechanisms that offer similar benefits to Automatic Dependency Injection, and evaluate their strengths and weaknesses.

I’m a big fan of Automatic Dependency Injection.
It saves time, it makes the code cleaner, and it works great for testing.
In the past, I built and used several Dependency Injection libraries, most recently in C# and in Objective-C.

How Is It Done in Objective-C?

One way of overcoming this limitation is to use Objective-C APIs. Doing so requires that all objects that need to be created inherit from NSObject, and I would like to move away from having to use NSObject inheritance for Swift classes.

While this approach works, I find the infrastructure code to be too lengthy. Furthermore, a parent object that handles the lifetime of a child object must pass along dependencies, making the code lengthier. Even if the parent object does not need the dependency, it still needs to receive it in the init, to use it for constructing the child object.

Take the following example:

Class Horn needs the SoundServiceProtocol dependency.

Class AdvancedVehicledoes not need the SoundServiceProtocol dependency for itself, but it does need it in order to construct the child object.

This approach moves the verbosity away from each class that needs access to a SoundService. Instead, the singleton ServiceLocator will have to be instantiated once, and afterwards all objects that need access to the service will have to use the static instance variable available on ServiceLocator.

While the code is much shorter than the 1st approach, when used by a consumer, the code used to call the service in each caller classes got bigger:

1st approach: soundService.makeSound()

2nd approach: ServiceLocator.instance.soundService.makeSound()

3rd Approach: Protocol Extensions

Building on 2nd approach, we can take advantage of the Swift protocol extension and the fact that you can define methods and properties that apply for all classes conforming to a protocol.

We define a new protocol named HasSoundService which only contains a computed property that is meant to simplify the access to the ServiceLocator.

Notice that we had to introduce a new protocol HasSoundService and write a computed property in an extension for that protocol. At the same time, each class that needs access to that property must conform the new HasSoundService protocol.

Conclusion

I found the 3rd approach to be the most versatile. By using the suggested infrastructure, the consumers gain easy access to the service they are interested in by conforming to a protocol.
I prefer this version because the syntax is concise and easy to remember as it does not alter the original methods of SoundServiceProtocol.
The only caveat is that infrastructure code must be written. The good news is that it only needs to be written once and makes consuming the resulting code much easier.

By using the Swift language features we managed to build a Dependency Injection-like mechanism that makes it easier to handle complex dependencies while keeping the code decoupled.

Where Is It Used

I use this approach on my new iOS game, Hexa Word Search. The goal of the game is to find words in a honeycomb structure.
If you’d like to try out an early version let me know.

Notice that the only different thing about the two styles is the color used as Foreground, the rest is similar. For the sake of simplicity I kept the myTextBlockStyle quite small, with only two properties.

For maximizing our code reuse we can try to refactor the two styles into a separate style as follows:

While developing Puzzle Frenzy, I took tons of wrong decision. On multiple occasions I assumed what my game players want and I implemented several features which were never used, or used by very few users.

However, over time I started to listen to what the users were asking for. By putting together all the communication channels I was able to come up with totally different features that I originally had in mind. And guess what?! by implementing those features suddenly I got more user engagement, better ratings and more downloads.

Being an game or app developer is not easy and surely poses a lot of challenges. For me, one of the biggest problem was that I was putting my judgement ahead of my users feature requests.

I soon as I realized that 50.000 voices are stronger than 1 (my own) the game development started to flourish.

For anyone out there interested in satisfying their users I have one golden advice: