As projects get larger, we can start to see some problems with living with a single Xcode project.
Many developers making changes can cause serious contention on the project file, storyboards and XIBs, which is painful. Build times get longer, and we may also need to reuse code between an app and an extension.
How can we architect our application to address these issues?
In this series we will explore a Modular Project Architecture and discuss the benefits you can expect. We'll show how to accomplish this with a few different strategies.
Length: about 3 hours
In this episode we will talk about the overview and motivation for a modular project architecture. Why split things up? I'll talk about the problems we face, what benefits we may achieve, and how can we approach the problem.
One way of achieving modularization is to build frameworks using nested Xcode projects. This has the benefit of having everything in one place and can easily build the entire thing. You can also zero-in on a single project and just work from there if you want. Each sub-project can have its own tests, sample application, etc.
Breaking your code into discrete modules will surface a problem if your code is tightly interconnected. Once you've defined your module boundaries you now are forced to not cause bidirectional dependencies. In this episode we will look at some strategies for breaking apart dependencies into abstractions first using protocols, then using protocol witnesses. We can then depend on those abstractions in our isolated module projects.
One thing that can be a pain when splitting modules up into separate projects is maintaining the Xcode projects themselves. Not to mention the fact that as team sizes grow, merging changes in project files gets exponentially more painful. In this episode we will look at using Xcodegen to have a repeatable project generation that you can use to create consistent Xcode projects without much fuss.
In this episode we create a modularized setup where our modules are Swift Packages and brought into the main app using Xcodegen and local path references to the packages.
One big benefit of modularizing an application is working on features as modules. Let's re-create the welcome screen experience as a feature module using Swift Package Manager and Xcodegen.
Now that we've seen how to setup a feature module, we'll also need to decide how best to share a feature's resources and deal with dependencies.
If you're using CocoaPods already, then mixing with Swift Packages can prove to be infeasible. You can create your modules as internal pods as well, however there are a few gotchas. In this episode I will cover how to do this, how to link up local pods and create example projects for demo UI and running tests, as well as how to overcome some of the rough edges you might experience.