Xcode ToolsMidOpen-ended

How do you create your own custom Xcode File Template from scratch?

Explanation & Code

Answer: To create a custom Xcode File Template from scratch, create a .xctemplate directory inside ~/Library/Developer/Xcode/Templates/File Templates/<Category>/, add a TemplateInfo.plist declaring the substitution kind and options, and create blueprint source files with ___FILEBASENAME___ in file names and ___VARIABLE_productName:identifier___ in source code.

Step-by-Step Guide

1. Create the Template Directory

Choose a category name (e.g., Architecture, Networking, VIPER, or your company name) and a template folder ending with .xctemplate:

mkdir -p ~/Library/Developer/Xcode/Templates/"File Templates"/Architecture/VIPERFeature.xctemplate
cd ~/Library/Developer/Xcode/Templates/"File Templates"/Architecture/VIPERFeature.xctemplate

2. Create TemplateInfo.plist

This file defines the template's metadata, picker UI, and user input variables:

<?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">
<dict>
    <key>Kind</key>
    <string>Xcode.IDEFoundation.TextSubstitutionFileTemplateKind</string>
    <key>Identifier</key>
    <string>com.mycompany.Architecture.VIPERFeature</string>
    <key>Name</key>
    <string>VIPER Feature</string>
    <key>Description</key>
    <string>Generates a complete VIPER module (View, Interactor, Presenter, Entity, Router).</string>
    <key>Summary</key>
    <string>Creates VIPER module files</string>
    <key>SortOrder</key>
    <string>1</string>
    <key>Platforms</key>
    <array>
        <string>com.apple.platform.iphoneos</string>
    </array>
    <key>Options</key>
    <array>
        <dict>
            <key>Identifier</key>
            <string>productName</string>
            <key>Name</key>
            <string>Feature Name:</string>
            <key>Description</key>
            <string>The base name of the module, e.g. Payment (no suffix).</string>
            <key>Type</key>
            <string>text</string>
            <key>Required</key>
            <true/>
            <key>NotPersisted</key>
            <true/>
        </dict>
    </array>
</dict>
</plist>

3. Create the Blueprint Source Files

Create a file for each component your architecture requires. Name the files using ___FILEBASENAME___<Suffix>.swift:

touch '___FILEBASENAME___Contract.swift'
touch '___FILEBASENAME___Presenter.swift'
touch '___FILEBASENAME___Interactor.swift'
touch '___FILEBASENAME___Router.swift'
touch '___FILEBASENAME___ViewController.swift'

4. Author Blueprint Contents with Placeholders

Inside each file, use ___VARIABLE_productName:identifier___ for class, struct, and protocol names:

//
//  ___FILENAME___
//  ___PACKAGENAME___
//
//  Created by ___FULLUSERNAME___ on ___DATE___.
//  ___COPYRIGHT___
//

import Foundation

/// Interactor logic for ___VARIABLE_productName:identifier___
final class ___VARIABLE_productName:identifier___Interactor: ___VARIABLE_productName:identifier___InteractorProtocol {
    weak var presenter: ___VARIABLE_productName:identifier___PresenterProtocol?

    func fetchData() {
        // Business logic here
    }
}

Crucial Rule:

  • In File Names: Use ___FILEBASENAME___ (e.g. ___FILEBASENAME___Interactor.swift).
  • In File Contents: Use ___VARIABLE_productName:identifier___ (e.g. final class ___VARIABLE_productName:identifier___Interactor).

5. Adding Advanced Template Options (Checkboxes & Dropdowns)

You can prompt for additional options like including unit test files or choosing between UIKit and SwiftUI:

<dict>
    <key>Identifier</key>
    <string>hasUnitTests</string>
    <key>Name</key>
    <string>Include Unit Tests</string>
    <key>Description</key>
    <string>Generate a test file alongside the module</string>
    <key>Type</key>
    <string>checkbox</string>
    <key>Default</key>
    <string>true</string>
</dict>

6. Validate and Test

Validate the plist syntax:

plutil -lint TemplateInfo.plist

Run an automated health check:

bash -c '
TPL=~/Library/Developer/Xcode/Templates/"File Templates"/Architecture/VIPERFeature.xctemplate
if [ -d "$TPL" ] && plutil -lint "$TPL/TemplateInfo.plist" >/dev/null 2>&1; then
    echo "✓ Template structure and plist are valid!"
else
    echo "✗ Check template folder or plist syntax."
fi
'

7. Restart Xcode and Generate

  1. Quit Xcode completely with ⌘Q (templates load once on startup).
  2. Reopen Xcode and open your project.
  3. In the Project Navigator, select the destination group.
  4. Go to File ▸ New ▸ File from Template…
  5. Scroll down to your custom category (e.g., Architecture), select your template, and click Next.
  6. Type the module name in Feature Name:, and type the same name in Save As:.

Rate your understanding:

Ready to practice more Xcode Tools?

Test yourself with our interactive quiz mode or browse all curated questions for this topic.