Lately I have been involved in several discussions around organizing files, groups and their representation in the file system in XCode. As you probably know, XCode allows you to organize files in groups. These groups look like directories, however any group structure you create will only exist in XCode. This grouping does is not reflected in the file system automatically.
In this context I have often been asked the following questions, which I will explain in detail below:
- What is a good group structure in Xcode?
- Do we have to mirror the XCode group structure to the file system and keep them in sync?
What is a good group structure in Xcode?
My current answer is: what works best for your project and team. For rather large projects, I start with the following structure and refine it as the project evolves. Let’s examine those entries one by one:
- ThirdParty. I use this as a container to drop third party libraries that are distributed as source code. Common examples are Reachability or AFNetworking.
- Core. This one is interesting, so let’s reach back a bit more. On larger projects, I almost always make a distinction between the Application itself and it’s core or framework. (I used the term framework before, but switched to core lately due to confusion with the default “frameworks” group XCode creates for you). So what goes into “Core” and what goes into “Application”? “Core” contains all functionality that is technically necessary for the app to work, generally of low-level nature. “Application” contains all functionality to that is semantically (in terms of the domain language of the project) and of high-level nature. Let me give you one example of this separation. Assume you have an app that has to talk to a REST interface to get data and present it on the screen. All the code required to talk to the REST service, parse responses into objects and notify observers about the presence of new data would go into “Core”. “Application” on the other hand, would only talk to a high-level service interface and say “give me a list of users and call my asynchronous notification handler when it’s there”. As you can see, the functionality that goes into “Core” is expressed in technical terms, where the functionality that goes into “Application” is expressed in terms of the domain language at hand.
- Application. Standard MVC style structure with extra groups for Utils and supporting files (created by Xcode).
Do I have to mirror the XCode group structure in the file system and keep both in sync?
This question has been subject of lengthy and sometimes heated debate. I really think that this is up to the team/developer. However, in order to make an educated choice, you should be aware of the pros/cons. On the con side, I would mention that keeping both xcode and the file system in sync takes an extra effort. Since this is not enforced by any tool, you have to keep it in mind. Further it can happen that your project ends up with two files with the same name, but in different directories. This will certainly cause xcode some hiccups.
On the pro side, if you, like me, do work in the command line sometimes or even edit files with vim, you will highly appreciate not doing so in a flat directory containing hundreds or thousands of files. These numbers can be reached quite quickly nowadays, especially if you take clean code seriously.
My rule of thumb is, if the project is likely to stay rather small, do not bother. If the project tends to be a rather large one, do think about keeping the groups and the file system in sync.
I hope this article can get the discussion going and lead to an increase of quality in your projects. As always, feel free to comment and let me know if you have your own structure in your projets.