Something all Xcode users will be familiar with is the process of creating new files. When the new file command is triggered, we are presented with a window containing a selection of templates to base our new file upon. These new templates often contain lines of code we immediately delete or code that needs to be changed to fit into our preferred style. Many people may be unaware that instead of relying solely on the provided templates, we can create our own and have Xcode present them to us. This can simplify the process of creating new files and allow them to match more specific requirements.

The process of creating templates can seem a bit confusing at first, but the end result can be really useful. We are going to explore the process of writing our own Xcode file templates, before delving into how we might go about sharing these with other developers on a particular project.

Creating a template

When Xcode launches, it looks for file templates within a specific location: ~/Library/Developer/Xcode/Templates/File Templates. To get started, we need to create a directory within here that will house all of our file templates.

mkdir -p ~/Library/Developer/Xcode/Templates/File\ Templates/Custom

Within this directory, a quick way to get started is by copying one of the built-in templates and then altering it. They can be found within the Xcode application bundle, with a good option for Swift-based templates being the one for a new Swift file, Source/Swift File.xctemplate.

/Applications/Xcode.app/Contents/
  > Developer/
    > Library/
      > Xcode/
        > Templates/
          > File Templates/

After copying the files, we find the xctemplate contains 4 different files.

  • TemplateIcon.png and TemplateIcon@2x.png are the thumbnails that are presented within the new file window. We could use these for all of our Swift templates or create specific ones of our own.
  • TemplateInfo.plist is where we configure our template.
  • ___FILEBASENAME___.swift contains the Swift source that forms the basis of the template.

We will start by creating a template for a new Swift struct, called Swift Struct.xctemplate, that is based upon the Swift File.xctemplate mentioned above.

→ TemplateInfo.plist

Within the property file we can change the Description and Summary keys to clearly describe the template within Xcode.

<key>Description</key>
<string>A Swift struct.</string>
<key>Summary</key>
<string>A Swift struct.</string>

→ ___FILEBASENAME___.swift

By calling the file ___FILEBASENAME___.swift, the resulting Swift file will be named according to what is entered into the new file window. This same argument can be used within the template using ___FILEBASENAMEASIDENTIFIER___. This means that if we enter Contact into the new file window, the generated file will be Contact.swift, containing the struct Contact.

struct ___FILEBASENAMEASIDENTIFIER___ {
}

Once completing the template, starting up Xcode and requesting a new file, we can find our template being offered within a section called ‘Custom’. The name of the section is controlled by the directory name we used within ~/Library/Developer/Xcode/Templates/File Templates.

Our new template shown within Xcode
Our new template shown within Xcode

What else can we do

Although they can start very basic, there are some more significant things we can do with templates.

  • Offer the option of Swift or Objective-C when creating a new file.
  • Change the filename based on what is entered, for example naming the file UsersRepositoryTests if UsersRepository is entered.
  • Ask for arguments to be entered in the new file window and then use these within the code.
  • Add file headers or copyright notices.
  • Add imports or skeleton code to be included in the file by default.

Some example file templates can be found on GitHub, demonstrating some of the options available.

It’s nice to share

As we explore the possibilities that file templates provide us, one problem becomes extremely clear. It would be really great if we could create project-specific templates and share them with the other developers on the project. Although templates for a specific project are not supported automatically by Xcode, it can be done through a clever use of symbolic links.

We should place all templates in a directory within our project, such as FileTemplates. It is likely the project is kept in source control, which will ensure the templates are tracked and shared with everyone else in the team.

The directory Xcode expects to find our templates should already exist if the steps were followed above. If not then we need to ensure it does.

mkdir -p ~/Library/Developer/Xcode/Templates/File\ Templates

Once the directory exists, the symbolic link can be created here that points to the templates within our Xcode project. It is worth mentioning that if we delete the project or move it, the symbolic link can simply be deleted and recreated.

ln -s [Project Location]/FileTemplates \
  ~/Library/Developer/Xcode/Templates/File\ Templates/[ProjectName]

For example:

ln -s ~/projects/github/chatapp/FileTemplates \
  ~/Library/Developer/Xcode/Templates/File\ Templates/ChatApp

After restarting Xcode, any project templates will now be presented within the ‘New File’ window. It would obviously be great if Xcode could offer a solution without the extra work, however, for now it works nicely.

That’s a wrap

Xcode file templates can be a great way to get started quickly when creating new files. They are very powerful, although quite under-documented and there is much more they can do than discussed here.

What do you think about Xcode file templates? Do you already use them or do you just put up with the default templates? I am sure there are some great things templates can do that I haven’t explored here, in which case I would love to hear about them! Please feel free to reach out to me on Twitter @lordcodes with any questions or thoughts you have, or about anything else.

If you like what you have read, please don’t hesitate to share the article and subscribe to my feed if you are interested.

Thanks for reading and happy coding! 🙏