Keep it Close

Sep 6, 2015

Structuring the files in a project in a scalable way usually doesn’t have the highest priority when you start your small app project, but with an increasing size of code and number of teammembers working on it, a good project structure can significantly improve the understandability of the project. I want to share my thoughts about what I think is the best approach for it.

Starting your project it might seem to be a good thing to sort your files based on their role in the MVC pattern. You create a group - or even better a group based on a folder! - for your controllers, one for your models, maybe one for networking stuff, one for custom UIViews and also one for auxiliary stuff.

This might look something like this:

As the project grows you discover that you need subfolders based on the features (e.g. one for the newsfeed, one for the chat and one for the store), so you add some in each folder:

Since you are a good programmer and write unit tests, you mirror the structure in your test directory and have an even larger tree!

What’s the problem with such a structure?

As your app grows you add more and more features and more and more subfolders in subfolders and so on. Now you want to make changes to one feature. Since it’s a complex change you need to modify your networking code for it, the model and of course the view controller. Also you need to adjust the unit tests. When you now try to use the project navigator you need to scroll all the time since you have to expand a total of 6 branches!

How can we do better?

Group by feature - not by responsibility:

When we’re editing one feature we now only have to expand 2 branches - one for implementations and one for tests.

But we can do even better! Since we’re not bound to packages and stuff like that, as we are in other languages (e.g. Java), and membership to a target (e.g. app or unit-test target) is configured in the project file itself, we can even move our unit tests close to the implementation!

The gist of it: Base your project structure on features and keep stuff that you need to edit at the same time close together. This makes navigation way easier and for new developers joining your team it’s a lot easier to understand the project and it’s features just by looking at the project structure.

It’s also nice to mirror your project structure in the file system. This makes it easier to find files without opening Xcode, to see which group a files belongs to in git logs and diffs and also if you browse the project on GitHub. Unfortunately Xcode doesn’t create folders for new groups automatically but you can easily assign a folder to group in the file inspector after selecting the group in the project navigator:

PS: You can also have multiple asset catalogues and storyboards per project - one per feature ;-)