How I Use Xcode's Template Library To Reduce Boredom
Tags: swift, ios, devops, codequality
Published: 2020-11-24 15:39:11

If you're anything like me, you make a lot of Xcode projects. You also may have noticed that if you like your projects organized a certain way, perhaps by a certain paradigm - then you're doing a lot of repetitive, boring work.

## Repetitive, boring, work? 
#### But... I'm a programmer

I know, right? Aren't we supposed to be automating things? I think we are. So why the heck are we manually rearranging our files and folders? Haven't we noticed yet that we can create different kinds of projects in Xcode and they come with different files and folders? 

## Have you ever wondered just how they generate all that code? Me too, so let's find out...

### What exactly can you generate with a template?
#### *files*, folders, groups, *dynamic lines of code*

In this tutorial, we'll be building a simple file template with dynamically generated code. Trust me... you definitely don't want me to cover everything you can do with a template in one tutorial. It's **a lot** - you can even customize entire projects up to and beyond editing and adding entries to your `info.plist` file. 

## Generating Files
#### With this:
![Screen Shot 2020-11-24 at 6.18.07 AM](https://dev-to-uploads.s3.amazonaws.com/i/rn7wa9gn73lyedpdh05s.png) 

#### You'll get to make a model file that conforms to Equatable, each time with a different name for the file and class:
![Screen Shot 2020-11-24 at 6.14.04 AM](https://dev-to-uploads.s3.amazonaws.com/i/esaz4v695998rdjgfbjv.png)

#### File->New->File Dialog
![Screen Shot 2020-11-24 at 6.16.26 AM](https://dev-to-uploads.s3.amazonaws.com/i/xmrshfet8xyyewvk2g1t.png)  

#### New Model With Equatable Conformance!
![Screen Shot 2020-11-24 at 6.18.58 AM](https://dev-to-uploads.s3.amazonaws.com/i/8zjly14jua4fx2kn5nbl.png)

# The Anatomy of a Template

At their core, templates are pretty simply woven together. You have a folder with the extension `.xctemplate` and a `.plist` file in that folder named `TemplateInfo.plist`. From there, you can make things pretty complex, but it's easy to get "in the weeds" pretty quickly. We could generate a file solely in the `TemplateInfo.plist` file if we use the right options and do everything just right, but let's keep this simple and see how you can start putting the Xcode Template engine to use right away to cut down on a little bit of boilerplate code.

## 1. Find the Folder Where Custom Templates Go

Xcode's default templates live in various places inside of the Xcode App Package. We could store our templates there, but then every time we update the Xcode app, they'll get replaced. The good news is, we have a place where we can more permanently store our templates.

Open up your finder window, and press `cmd`+`shift`+`g`

![Screen Shot 2020-11-24 at 6.34.38 AM](https://dev-to-uploads.s3.amazonaws.com/i/qlpt7274i3aiz4ucpp49.png)

Type in the following path `~/Library/Developer/Xcode/Templates` and click Go

Congrats! You're inside of the custom template folder. Now let's create our first custom template. The first thing you'll want to do is create 2 separate folders to organize your Templates. Name one `File Templates` and the other `Project Templates`.

# 2. Create Your Template Folder
Now, open the `File Templates` folder, and create a new folder. Name this whatever you'd like, but make sure to end the folder name with `.xctemplate`. For example, `devTo.xctemplate`.

# 3. Create Your `TemplateInfo.plist`
Inside of the `xctemplate` folder you just created, we're going to need to create a `TemplateInfo.plist` file. This is kind of like template inception, but let's create a new `.plist` file using Xcode's existing `.plist` file template.

Open up Xcode and choose `File->New->File`. Select Property list (I like to filter the files so it's easier to find).

![Screen Shot 2020-11-24 at 6.43.13 AM](https://dev-to-uploads.s3.amazonaws.com/i/td029esrcjw0dggbne4s.png)
 
Now, you'll need to navigate to the `xctemplate` folder you just created in `~/Library/Developer/Xcode/Templates`. ⚠️Important!⚠️ name this file `TemplateInfo.plist`. 
#### NOTE: Sometimes the easiest way to put this file in the right folder is to save it to your desktop, then move it there manually using `cmd`+`shift`+`g` in Finder.

# 4. Start Populating Your `TemplateInfo.plist`
Once you've created the `TemplateInfo.plist` file and have it in the right directory, it's time to create your template! Open your `TemplateInfo.plist` file and create a new entry by clicking the small plus sign that appears when you hover over an existing row.

![Screen Shot 2020-11-24 at 6.51.27 AM](https://dev-to-uploads.s3.amazonaws.com/i/xj4rs3k25x0mgv8amq1q.png)

### Identify what type of template this is.
By default this shows a list of values such as `Bundle Identifier`. We're first going to identify this template as a file template. In order to do that, we'll need to name this entry `Kind`. Leave the type as String and double click where the value would be to input a new value. 

Copy and paste `Xcode.IDEKit.TextSubstitutionFileTemplateKind`, and Xcode will know this is a file template rather than project template.

![Screen Shot 2020-11-24 at 7.02.41 AM](https://dev-to-uploads.s3.amazonaws.com/i/s27pwkr7qq7x6p69kzp9.png)

### Identify which platform(s) this template can be used on. 

We'll use this on iOS. Create a new Entry named `Platforms` and change the type to `Array`.

![Screen Shot 2020-11-24 at 7.04.45 AM](https://dev-to-uploads.s3.amazonaws.com/i/ebs7n0732se5e3dfvxvv.png)
 
Now, click the small dropdown next to Platforms and create a new entry. This should create Item 0. For the value, enter `com.apple.platform.iphoneos`

![Screen Shot 2020-11-24 at 7.07.20 AM](https://dev-to-uploads.s3.amazonaws.com/i/g2vm2vkjqi6qkt0zuek1.png)

# 5. Create Options
Collapse Platforms and create a new entry called Options. Make this an `Array`. Options is an Array that contains Dictionaries. These Dictionaries define text boxes, checkboxes, dropdowns, combo boxes, and static text. Each gets its own unique identifier and can be used to populate fields. 

First, we're going to create an option with an Identifier of `productName`. `productName` is a special identifier that can be referenced throughout the template as either `___FILEBASENAME___` or `___FILEBASENAMEASIDENTIFIER___`. `FILEBASENAME` references the name exactly as input while `FILEBASENAMEASIDENTIFIER` references the name in a way that can be used for class names, variables, and more by stripping out special characters and spaces.

1. Expand the Options Array and create a new entry. 
  - Make this type Dictionary. 
2. Expand the Dictionary (item 0) and create a new entry.
  - Name this Identifier. Give it a value of `productName`
3. Create a new entry in the Dictionary named Description.
  - Give it a value of "`Enter Name`" (no quotes)
4. Create a new entry named Name.
  - Give it a value of "`Enter Name`"
5. Create a new entry named Default.
  - Give it a value of "`Model Name`"
6. Create a new entry named Required. Make the Type Boolean
  - Give it a value of 1 (true)
7. Create a new entry named Type.
  - Give it a value of text

![Screen Shot 2020-11-24 at 7.26.16 AM](https://dev-to-uploads.s3.amazonaws.com/i/it93ap5qq014i4tlt7nt.png)

#### Here's what this does:
- 2. Our default identifier we use in the file.
- 3. The tooltip that appears when you hover over the option
- 4. The text that appears next to the option
- 5. The option's default value
- 6. Whether or not the option is required to have a valid value in order to create the template.
- 7. The type of option this is. Text makes this a text box.

# 6. Create Your File!
I like to do this from terminal to get a fresh file, but you can do it from Xcode and use the blank template or Swift File template. Using the Swift File template includes the header though, and you can choose to include or exclude it with your own blank file.

No matter your method, create a new file named `___FILEBASENAME___.swift`. This will name the file after whatever you type in the text box when you choose this template in Xcode.

I'm going to create a model file with the header included (`___FILEHEADER___`). Feel free to make whatever you'd like! 🧑‍💻👩‍💻

Anywhere you would normally type the name of the file/struct/class/whatever - you can substitute that with `___FILEBASENAMEASIDENTIFIER___`

![Screen Shot 2020-11-24 at 7.31.31 AM](https://dev-to-uploads.s3.amazonaws.com/i/l2vuop0spmm5kxknj7a1.png)

Save this file in the same place you saved your TemplateInfo.plist file. Now, the next time you open Xcode, go to `File-New->File` and behold the glory of your template!

![Screen Shot 2020-11-24 at 7.49.47 AM](https://dev-to-uploads.s3.amazonaws.com/i/qaua2ystpk32qqivuqae.png)
 
![Screen Shot 2020-11-24 at 7.50.16 AM](https://dev-to-uploads.s3.amazonaws.com/i/3999ujwihu3dizdhm1yh.png)

![Screen Shot 2020-11-24 at 7.50.40 AM](https://dev-to-uploads.s3.amazonaws.com/i/r7cu6dscv8qu7tccx4zc.png)  

# Free From Boredom, Safe From Mistakes
I've created several file templates and a few project templates of my own, some that I use on a frequent basis. This helps me not waste so much time typing boilerplate code because I only have to make one template and it's done **forever**. More importantly, it gives me the confidence and security knowing that my initial implementation will work, because it worked last time. Create your templates with the best of care and intentions, and you have something you can use that's safe, reliable, and **fast**.

Drop a note in the comments about your experience with Xcode Templates.

#### Happy Templating!