Every app we build is unique, but best practices should be consistent between projects. Here on Vokal’s iOS team, we’ve been baking more and more of those best practices into a template we use for starting any new project.
This ensures consistency in our work: we don’t repeat mistakes, we use known libraries that we all have some experience with, and any one of us can get up to speed on a new project quickly because things are organized in a way we recognize.
What started as a simple Xcode project template has grown over the past two years into two separate project templates, a number of other templates for test and aggregate build targets, and a suite of scripts and configuration files. These templates are now open source and available on GitHub!
When creating a new project from one of our templates, you get a lot of things right from the start:
- Configuration for our private podspec repo, plus some of the CocoaPods we use regularly like KIF and VOKMockUrlProtocol
- Vokoder and a helper utility, if you choose to include Core Data
- A starter network utility for REST APIs, if you choose to include AFNetworking or Alamofire
- Configuration for Travis CI
- Our standard lanes for fastlane, along with config files for some of the fastlane tools we use
- A config file containing our coding standards, for use with Objective-Clean or SwiftLint
- Separate test targets for UI and unit tests
- Code generation scripts, for Cat2Cat, mogenerator, and R.swift
- Build scripts for xUnique and build number incrementation
Apple doesn’t provide documentation on setting up project templates, but thankfully, quite a few third parties have shared how-to guides over the years. The format for the template files hasn’t changed much in several years, so a lot of that information is still useful. Still, we had to rely on quite a bit of trial-and-error along the way to get everything we wanted into our fresh new projects. There’s also some things one just can’t do from a project template (as far as we have been able to determine, anyway), so we have a few steps that must be completed manually after creating a new project; these are detailed in the template README.
If you look at our repo, you may wonder why we have separate templates for Objective-C and Swift. When we started our project template, we based it on those provided by Apple. Their templates have a Language dropdown to choose Objective-C or Swift, and when you create the project, the boilerplate code is in the chosen language. Unfortunately, we found this very hard to maintain. All of that boilerplate code is inside of the XML document that defines the template, and maintaining XML is painful enough without trying to maintain Objective-C and Swift inside of it.
We quickly found that as we added more and more starter code to the template (like the network and Core Data utilities, unit tests for said, and so on), keeping it all in one template was becoming a big headache. As such, we kept some common items in a parent template, and split the Objective-C and Swift templates off as children of that common ancestor, so that it’s easier for us to continue adding to those helpers and utilities that we use in every project.
If you’re interested in bundling your best practices into a template, or just curious to see how we did, take a look at the repo and let us know what you think!