Learn how to organize your codebase. If you are struggling with Xcode project structure, files, naming conventions, read this!
Apple has so much frameworks and APIs that I don't even know many of them. We are also living in the age of application extensions. If you are trying to create a brand new target in Xcode, you might end up scratching your head. 🤔
This is great for both for developers and end-users, but after creating a few targets and platforms (your project grows and) you might ask the question:
How should I organise my codebase?
Don't worry too much about it, I might have the right answer for you! 😉
You can create apps in Xcode for all the major operating systems: iOS, macOS, tvOS, watchOS. In the latest version of Xcode you can also add more than 20 extension just for iOS, plus there are lots of app extensions available for macOS as well. Imagine a complex application with multiple extensions & targets. This situation can lead to inconsistent bundle identifiers and more ad-hoc naming solutions. Oh, by the way watchOS applications are just a special extensions for iOS targets and don't forget about your tests, those are individual targets as well! ⚠️
As far as I can see, if you are trying to support multiple platforms you are going to have a lot of targets inside your Xcode project, additionally every new target will contain some kind of source files and assets. Should I mention schemes too? 😂
Even Apple removed it's Lister sample code, that demonstrated one of a hellish Xcode project with 14 targets, 11 schemes, but the overall project contained only 71 Swift source files. That's not too much code, but you can see the issue here, right?
It's time to learn how to organise your project! 💡
So my basic idea is to have a reasonable naming conceptand folder structure inside the project. This involves targets, schemes, bundle identifiers, location of source files and assets on the disk. Let's start with a simple example that contains multiple targets to have a better understanding. 🤓
Quick note:If you are using the Swift Package Manager eg. for Swift backends, SPM will generate your Xcode project files for you, so you shoudn't care too much about conventions and namings at all. 🤷♂️
Are you creating a new application? Feel free to name your project as you want. 😉
Are you going to make a framework? Extend your project name with the "Kit" suffix. People usually prefer to use the "ProjectKit" style for libraries so that's the correct way to go. If you have a killer name, use that instead of the kit style! 😛
Always use the following platform names:
Name your targets like:
[platform] [template name]
Simply use target names for schemes too (prefix with project name if required).
[project] - [platform] [template name]
You can prefix schemes with your project name if you want, but the generic rule is here to use the exact same name as your target. I also like to separate framework schemes visually from the schems that contain application logic, that's why I always move them to the top of the list. However a better approach is to separate frameworks into a standalone git repository & connect them through a package manager. 📦
This one is hard because of code signing. You can go with something like this:
[reverse domain].[project].[platform].[template name]
Here are the rules:
.watchkitextensionfor legacy watchOS targets
Quick note:If you are going to use `com.example.project.ios.today.extension` that's not going to work, because it contains more than 4 dots. So you should simply go with `com.example.project.ios.todayextension` and names like that. 😢
Anyway, just always try to sign your app and submit to the store. Good luck. 🍀
The thing is that I always create physical folders on the disk. If you make a group in Xcode, well by default that's not going to be an actual folder and all your source files and assets will be located under the project's main directory.
I know it's a personal preference but I don't like to call a giant "wasteland" of files as a project. I've seen many chaotic projects without proper file organization. 🤐
No matter what, but I always follow this basic pattern:
Sources I always make more subfolders for individual VIPER modules, or simply for controllers, models, objects, etc.
Here is a quick example project in Xcode that uses my conventions.
As you can see I followed the pattern from above. Let's assume that my project name is TheSwiftDev. Here is a quick overview of the full setup:
Target & scheme names (with bundle identifiers):
Quick note:If you rename your iOS target with a watchkit companion app, be careful!!! You also have to change the `WKCompanionAppBundleIdentifier` property inside your watch application target's `Info.plist` file by hand. ⚠️
This method might looks like an overkill at first sight, but trust me it's worth to follow these conventions. As your app grows, eventually you will face the same issues as I mentioned in the beginning. It's better to have a plan for the future.
I hope you liked this article, subscribe for more & follow me on Twitter for daily updates & Swift tricks & tips! If you want to support my work, contact me.
You should check out my favorite continuous integration & delivery service, because those guys at Bitrise are creating a truly amazing piece of software. It's time to automate your development workflow: save your time, try Bitrise!Sign up for FREE Thank you for your support
Subscribe to my monthly newsletter. On the first Monday of every month, you'll get an update about the latest Swift news including my articles and everything what happend in the Swift community as well.