Xcode Templates

Xcode Templates

We encounter Xcode Templates every time we want to create a new file or a project. Xcode provides numerous templates targeted at different platforms and languages.

File templates create different source code files, UI resources, asset catalogs, GPX files and such.

Project templates create the skeleton of a whole project, together with included UI resources (if needed), source code files and assets. They also provide library and framework creation.

Where can you find Xcode Templates source code?

Xcode looks for templates in two places:

1) Inside Xcode app bundle:

  • /Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/

2) In you Mac’s Library folder:

  • /Library/Developer/Xcode/Templates/

The latter path lets you add your own templates or third party ones, to your workflow.

General structure of a template

All templates are defined in XML, and contain a basic structure:

  1. Directory with the extension xctemplate
  2. TemplateInfo.plist
  3. Additional resources and files (if needed)

TemplateInfo.plist

Every template has TemplateInfo.plistthat defines it.

It has the following parts:

  1. Header definition
  2. Dictionary with options
  • 1) Swift Package support
  • 2) The kind of template
  • 3) Description, Summary and Sort order
  • 4) Allowed types for that template kind
  • 5) Platforms
  • 6) Default completion name
  • 7) Main template file
  • 8) Options dictionary

A) Header definition

It defines version, encoding and the property list type:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">

B) Dictionary with options

This is the body of a template and it defines a kind of template, supported platforms, packages, options and the similar.

The parts of that dictionary are described below.

1. Swift Package support

<key>SupportsSwiftPackage</key>
<true/>

2. Template kind

<key>Kind</key>
<string>Xcode.IDEFoundation.TextSubstitutionFileTemplateKind
</string>

There is also a Core Data template value: Xcode.IDECoreDataModeler.ManagedObjectTemplateKind .

For project templates the kind is:
Xcode.Xcode3.ProjectTemplateUnitKind

3. Description, Summary and Sort order

Sort order is used in a file template dialog.

<key>Description</key>
<string>An empty Swift file</string>
<key>Summary</key>
<string>An empty Swift file</string>
<key>SortOrder</key>
<string>1</string>

4. Allowed types

Source code language

<key>AllowedTypes</key>
<array>
	<string>public.objective-c-source</string>
	<string>public.objective-c-plus-plus-source</string>
</array>

Some types are:

  • public.swift-source
  • public.objective-c-source
  • com.apple.iig-source
  • com.apple.dt.playgroundpage
  • public.c-plus-plus-source
  • com.apple.metal

5. Platforms

Lists Apple platforms allowed

<key>Platforms</key>
<array>
	<string>com.apple.platform.macosx</string>
</array>

6. Default completion name

Name of file that will be generated when that template is selected

<key>DefaultCompletionName</key>
<string>File</string>

7. Main template file

The name of the template file that will be used when generating a new file. That file is included in the .xctemplate folder

<key>MainTemplateFile</key>
<string>___FILEBASENAME___.swift</string>

8. Options dictionary

This is optional and it defines the additional options that the user is gives when choosing that template.

Let’s look at one included template:

<key>Options</key>
<array>
	<dict>
		<key>Identifier</key>
		<string>productName</string>
		<key>Required</key>
		<true/>
		<key>Name</key>
		<string>Name:</string>
		<key>Description</key>
		<string>The name of the file to create</string>
		<key>Type</key>
		<string>text</string>
		<key>NotPersisted</key>
		<true/>
	</dict>
	<dict>
		<key>Identifier</key>
		<string>WithHeader</string>
		<key>Name</key>
		<string>Also create a header file</string>
		<key>Description</key>
		<string>Whether to create a header file with the same name</string>
		<key>Type</key>
		<string>checkbox</string>
		<key>Default</key>
		<string>true</string>
		<key>NotPersisted</key>
		<true/>
	</dict>
</array>

It will produce a dialog like this:

Two options are defined

Text option

<key>Type</key>
<string>text</string>

Checkbox option

<key>Type</key>
<string>checkbox</string>

And two files are supplied in the folder that has the same name as that option:

<key>Identifier</key>
<string>WithHeader</string>

Xcode File Templates

File templates produce one or more files, depending on the Options dictionary in the TemplateInfo.plist, and user selection, from the provided dialog.

Xcode Project Templates

Project templates allow inheritance , they also define targets, app lifecycles and more. Therefore the TemplateInfo.plist is extended with more options.

Project templates also define Base template parts:

  • Base template
  • Base Application template (like Build Phases, languages, main file)
  • Base App Extensions template
  • Base App Lifecycle template
  • Base Plist template
  • Base Language Definition template
  • Base Options template
  • Base Project Settings template
  • Base Bundle template
  • Base Framework template
  • Base Language Choice template
  • Base Metal Library template
  • Base Critical Security template (Settings Apple wants to be the default for security-critical codebases)
  • Base Test Bundle template
  • Base UI Test Bundle template
  • Base XPC Service template

From those parts all other project templates are comprised.

TemplateInfo.plist for project templates

This Plist is richer that the one for files:

Identifier

<key>Identifier</key>
<string>com.apple.dt.unit.multiPlatform.app</string>

Ancestors

It lists the templates that this template inherits from:

<key>Ancestors</key>
<array>
   <string>com.apple.dt.unit.base</string>
   <string>com.apple.dt.unit.languageChoice</string>
   <string>
</array>

Concrete

<key>Concrete</key>
<true/>

Name of the initial file

<key>NameOfInitialFileForEditor</key>
<string>ContentView.swift</string>

Options array

It lists options to include from the inherited templates.

For example a template may use options defined in another inherited template:

<key>Options</key>
	<array>
        <dict>
            <key>Identifier</key>
            <string>languageChoice</string>
            <key>Override</key>
            <string>Swift</string>
        </dict>

This template is using languageChoicedefined in a template with identifier: com.apple.dt.unit.languageChoice

	<key>Options</key>
	<array>
		<dict>
			<key>Identifier</key>
			<string>languageChoice</string>
			<key>Units</key>
			<dict>
				<key>Objective-C</key>
				<dict>
					<key>Definitions</key>
					<dict/>
				</dict>
				<key>Swift</key>
				<dict>
					<key>Definitions</key>
					<dict>
						<key>*:imports:importHeader:*</key>
						<string></string>
						<key>*:imports:importFramework:*</key>
						<string>import ___*___</string>
						<key>*:class:*</key>
						<string></string>
						<key>*:implementation</key>
						<dict>
							<key>Beginning</key>
							<string>class ___*___ {
</string>
							<key>End</key>
							<string>
}
</string>
							<key>Indent</key>
							<integer>1</integer>
						</dict>
						<key>*:implementation:methods:init</key>
						<dict>
							<key>Beginning</key>
							<string>override init() {
    super.init()
</string>
							<key>End</key>
							<string>}

</string>
							<key>Indent</key>
							<integer>1</integer>
						</dict>
					</dict>
				</dict>
			</dict>
		</dict>
	</array>