Modular Apps with a Tuist — Part 4 — Catch & Home

A step-by-step code walkthrough converting an existing app to a modularised app using tuist.

In the previous article I covered how to refactor the UI code into a module, create a testing app, how to write a simple template to use with the scaffold feature to generate a target for shared code and some of the mistakes along the way when adding dependancies — Yeah, a bit too much for just one article, I know, but it’s a journey. There really is a lot of work, even in such a small app. This article is a lot less ambitious — I will only refactor both the Catch and Home scenes into separate modules, which is mostly a rinse and repeat of what has already been covered. If you have actually read all 3 previous ones and followed through the code, congratulations, you deserve a medal: Light reading it isn’t.

The repo for this series is here

Catch If You Can

The repo now has 4 projects and multiple targets in each, and as I refactor out the monolith each framework / target is more focused on a small part of the total. The only real difference between the Catch and Backpack scenes is that Catch has a dependancy on the network module. But there is a catch (pun intended) — the example project needs to load all the SPMs that are required for the main Pokedex project since they cannot (currently) be encapsulated into the NetworkKit target (with this commit). Other then that though it is all the same as has been done in the last 2 articles with no new gotchas. The example app mocks the Home scene and tapping on the button opens the Catch scene as expected, and the image resources for the scene are internal to the framework.

let placeholderImage = UIImage(named: “PokemonPlaceholder”, in: Bundle(for: CatchViewController.self), with: nil)

Just remember that Bundle:for requires a class, so a struct won’t do.

The Home Run

The last module that needs a refactor is HomeUI. It contains the home scene and the image assets used. This work is really trivial compared to the other modules, although it did have a name collision when it came to the UITesting target (a problem solved in the previous article). Since the chosen architecture in this project incorporates the Coordinator pattern, the HomeUI doesn’t even need any dependancy to be injected to show the other screens as this functionality is fully described in the Coordinator source — it is so simple in fact. And this means less test cases to cover and less possible bugs. A win-win.

The Final Graph

The starting point was the blue Pokedex project, and the yellow shapes are the 6 modules that have been defined in this series. The brown folders are the SPMs defined as dependancies to the main app and the networking module. The green shapes are the test targets for each module.

The above image uses the tuist graph command to generate the image. The initial goal set out at the beginning has now been achieved — except for one small detail. I didn’t split out the core from the main Pokedex project as it wasn’t necessary. Apart from that I think that the fact that refactoring the HomeUI was such an effortless task that this whole approach to project modularisation is justified. It’s an elegant solution to what is usually a complex and tiresome problem to manage on a day-to-day basis.

This Is The End — Or Is It?

The goal has been reached. I am done. It is completed. Now what? Well, a few of things do need some more attention.

I mentioned a couple of times that this really isn’t the best approach to tuist projects, and in fact it could be merged into a simpler hierarchy. That will be the subject of another article soon. 🚧

Next, although Moya has some syntax that I like, it does add a lot of baggage in the form of other dependancies which for this project, and quite possibly most others just isn’t needed. In fact in the current major project I have been working on, no 3rd party networking library is used at all. So sorry Ash Furrow, and the rest of the team that have diligently laboured on this and the other more known library (AlamoFire) — I think it is time from them to be removed. 💩

In case you haven’t noticed (🙈🙉), Apple has made quite a bit of noise about SwiftUI in the last 2 years, so replacing all the UIKit scenes with SwiftUI would be interesting, but not essential. I’d still do it though. 😇

Keeping Up With The Tuist Releases

I started this series of articles on tuist version 1.36, and at the time of writing this has advanced to 1.46. There are some new features on the way like caching dependancies as binaries, thus reducing build times which I will have to incorporate in the coming weeks. So, as they say on the radio — stay tuned.

Please follow to receive all the next articles as they are published.

The completed code for this article is here.




Lead engineer at eDreams, iOS Software developer and electronic music fan

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Code Generation: There and Back Again

2021–01 BigQuery SQL Workspace and UI changes

This article has resonated with many people so I’ve formed a structured 30-day challenge if you…

My journey becoming a Unity game developer: Complete Level Cutscene-Fade effects added to the scene

How to have an API REST in 10 minutes with Strapi 🔵

Asynchronous Programming Meaning

A guide to SortedList (part 2/5) — Deep dive into data operations

Laravel 5.7 — Blade Layout Files

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
Ronan O Ciosoig

Ronan O Ciosoig

Lead engineer at eDreams, iOS Software developer and electronic music fan

More from Medium

Remote Notification in iOS Simulator — Xcode 11.4 or later & iOS 13.4 or later

How could you set up live rendering? — UIKit Swift 5

Regular Expression aka RegEx

Dependency Diagrams 411