Custom Xcode Template for Static Library in iOS

If you used Xcode then its certain that you come across and used templates for your projects. These can be file or project type templates such a Cocoa Touch Class, Storyboard, Core Data, Dynamic or Static Libraries. These are default templates which are bundled up with Xcode and for most of our use cases these should be sufficient, however if you are having to duplicate a certain functionality many times then things can get repetitive and inefficient. Lets say you have a policy of running a certain build script (SwiftLint for example) for all your project frameworks, you then have to introduce that script every time you introduce a new framework to your project. Soon this can get tedious especially when you have to introduce other functionalities such as Build Configurations.

Fortunately this process can be made easier by introducing Custom Templates. In this article i hope to example how one can create a custom Static Library template with pre-baked linting and custom configurations. This tutorial can also be used to create other project types such as dynamic libraries.

Where to store your templates?

Your custom templates are stored under the following path ~/Library/Developer/Xcode/Templates. When you first navigate to this path you may find it empty, this is expected as you may not have any custom templates. In your Templates folder you first create a folder called Project Templates. This folder will then hold all your project templates. If you want to create file templates then you create a folder called File Templates. It is important to get the names correct otherwise Xcode wont recognise your custom templates.

Lets create some more folders…

In your Project Templates folder you then create a folder to group your templates and you can call it what ever you like but for now lets call it Personal Static Libraries. This folder is where we are going to add our custom templates.

The template folders are suffixed with .xctemplate, so lets create a folder called StaticFramework.xctemplate. Your .xctemplate folder contains all the required files to support your custom templates, with the most important file being the TemplateInfo.plist.

TemplateInfo.plist is where you define your template properties and settings such as the template types, build script, build configurations, nodes etc. These are unfortunately a fraction of the properties you can adopt but don’t be overwhelmed because you can copy the Xcode’s default templates and tweak the relevant information to create your custom templates. This will save you time having to write boilerplate template code for your custom templates.

Before we dive in to see how to utilise the default templates, lets cover some important properties in the TemplateInfo.plist file.

  1. Kind: A string type used to identify the template type for example you use Xcode.Xcode3.ProjectTemplateUnitKind for project templates and use Xcode.IDEFoundation.TextSubstitutionFileTemplateKind file templates.
  2. Identifier: A unique identifier for a template. Used to uniquely identify a template or to inherit properties from ancestry templates more on that later.
  3. Concrete: A Bool type. Must be set to YES for Xcode to show your template when choosing a template for your project. If missing or set to NO Xcode treats the template as an abstract base template that other templates can inherit from.
  4. Ancestors: An Array type to hold a collection on Identifier, used to inherit from other templates.

Copying the default static template

The following path is where default templates are stored: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates. If your Xcode app name is called other than Xcode then don’t forget to replace Xcode.app with the appropriate name in the path.

Navigate to the Project Templates/iOS/Framework & Library from the above path and copy the content of Cocoa Touch Static Library.xctemplate folder to your StaticFramework.xctemplate folder. Now you might be wondering what some of the files mean, lets take a look.

  1. ___PACKAGENAMEASIDENTIFIER___: The Objc and Swift files are default files you get when you create a project based on the selected language. For a Swift static lib you obtain the ___PACKAGENAMEASIDENTIFIER___.swift and for Objc you obtain the .h and .m files. Macros are used as file names so they are replaced on project creation. For more info on what macro to use visit here.
  2. TemplateIcon.png: These are optional png files used to spice up your custom templates, so that its more recognisable.

Setting an identifier

As mentioned previously it is important for the identifier of a template to be unique. The default templates provided by Apple uses a com.apple.dt.unit prefix, so every template provided by them has it. For our custom template we have to provide our own identifier prefix. I decided to go for com.personalLibrary.dt.unit but feel free to use your own.

Setting up swiftlint

Paste the following dictionary as an array item to BuildPhases under the first item in the Targets array in TemplateInfo.plist to setup swiftlint.

<dict>
<key>Class</key>
<string>ShellScript</string>
<key>Name</key>
<string>Run SwiftLint</string>
<key>ShellPath</key>
<string>/bin/sh</string>
<key>ShellScript</key>
<string>$(git rev-parse --show-toplevel)/Tools/SwiftLint/swiftlint --path ${SRCROOT}</string
</dict>

The above ShellScript will perform Linting on all files in the root of your static lib, off course the above script will only work if the static lib was added to your project which contains the swiftlint executable under /Tools/SwiftLint. But remember to introduce the appropriate changes (if any) according to your swiftlint setup.

Setting up Build Configuration

Paste the following to the root dictionary in TemplateInfo.plist to setup build configurations.

<key>Project</key>
<dict>
<key>Configurations</key>
<dict>
<key>Debug</key>
<dict/>
<key>Stage</key>
<dict/>
<key>AppStore</key>
<dict/>
</dict>
</dict>

The above setup will add 3 configurations to our static lib, Debug, Stage and AppStore.

Now that we finished adding all the appropriate properties to our TemplateInfo.plist we can now test it by creating a new Static library using our custom template by going to File -> New -> Project. When you do that you should see something like this (you may have a different icon😎):

It is important to note that if the Concrete property was set to NO in our TemplateInfo.plist then we would not see our custom template, Xcode treats the template as an abstract base template that other templates can inherit from. You may have noticed that the template shown above is grouped under the name Personal Static Libraries because the .xctemplate folder inside is hosting a non Concrete type template.

If you have any issues with your setup please comment below and i will try my best to help out 😊. Also check out my repo on Project templates where i am using inheritance to create custom templates for dynamic and static libs so that build configurations and build scripts are not copied but reused.

A Software Engineer with a passion for technology. Working as an iOS Developer @BBC

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store