Xcode Project and File Templates

Learn how to create custom project and file templates in Xcode to start new projects and files more efficiently. By Keegan Rush.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 2 of 4 of this article. Click here to view the first page.

Contents of a Template

You’re now going to look at the template you just created to learn what makes up a template.

Go back to Finder and open View Model App.xctemplate.

Inside the template, you’ll find:

  • TemplateInfo.plist: The file which is the driving force behind the template. This file contains the logic that determines what you’ll see in the New Project dialog and how to interpret any user input.
  • Any other files that will be used to form the template project. Currently, you’ll only see Main.storyboard as that’s the only file necessary to kick off the project.

Usually, a SwiftUI app starts with a ContentView.swift file, but it’s missing from this template folder. That’s because this template inherits ContentView.swift indirectly from another template called iOS SwiftUI App.xctemplate, located in the same folder as the original App.xctemplate you copied.

App.xctemplate inherits from Core Data Cocoa Touch App.xctemplate, which in turn inherits from iOS SwiftUI App.xctemplate. It’s templates all the way down! :]

Now that you’ve reviewed the templates, you’ll create a template ViewModel.swift file and connect it with your custom template’s ContentView.swift. This will be the first customization of the template you’ll do to start seeing the power of custom templates!

Customizing the Project Template

The first step to customizing your project template is creating a view model class.

Open Terminal.app and enter the following:

touch ~/Library/Developer/Xcode/Templates/View\ Model\ App.xctemplate/ViewModel.swift
Note: Make sure you’ve created View Model App.xctemplate with the exact name and location as instructed, or the previous command won’t work.

Terminal to run the touch command to create ViewModel.swift

This command creates an empty ViewModel.swift file within your template.

ViewModel.swift added in the custom project custom template

Next go back to Finder and open ViewModel.swift in Xcode. At the moment, it’s blank, so add the following code to its contents:

//___FILEHEADER___

import Foundation
import Combine

class ViewModel: NSObject, ObservableObject {
  @Published var title = "Hello, world! :]"
}

This creates a template ViewModel class that will drive your app’s view behavior.

With the code above, you’ve done a few things:

At the top is the ___FILEHEADER___ text macro. This macro is defined by Xcode and populates the file with copyright information, including your name, the current date, and the file name. ___FILEHEADER___ looks like this:

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

After ___FILEHEADER___, the code added the necessary imports and defined the ViewModel class containing a title string for now.

Save and close ViewModel.swift.

Your template will now create ContentView.swift from the inheritance described earlier and also ViewModel.swift from the file you just added. But you haven’t done anything to tell your template to add these files to a new Xcode project. To do this you’ll dive into TemplateInfo.plist. First, take a look at what the TemplateInfo.plist contains.

Working With Project Template Info

TemplateInfo.plist is the brains of your template. It instructs the template how to connect with ViewModel.swift. Next, you’ll explore TemplateInfo.plist‘s contents and create those instructions.

Open TemplateInfo.plist with Xcode.

Custom Project TemplateInfo.plist in Xcode

Below are some essential keys you’ll find inside the property list:

  • Kind: The type of template. In this case it is Xcode.Xcode3.ProjectTemplateUnitKind, which means it’s a project template.
  • Identifier: A unique identifier for your template.
  • Ancestors: A list of identifiers of other templates that this template inherits from. You’ll see two items in this array: com.apple.dt.unit.coreDataCocoaTouchApplication and com.apple.dt.unit.sceneLifecycleApplication.
  • Concrete: Indicates if the template is available directly while creating a new project in Xcode. Since you want to use this template to create a custom project, set it to true. If set to false, you can’t use the template directly as it will be an abstract base template from which your other templates can inherit information.
  • Description: A short description of the template.
  • SortOrder: Usually, Xcode arranges templates alphabetically, but you can set the sort order here to override the alphabetical sorting.
  • NameOfInitialFileForEditor: Indicates the file that Xcode will display once the new project is ready.
  • Options: A list of different dialog options in the New Project dialog. Options is the most complex as well as the most important of all the keys. Using Options, you can ask the user for input in the form of text fields, checkboxes and drop-down lists. Additionally, the Options section determines how to interpret user input.

Next, you’ll learn more about these options so you’ll know what “options” you have when you’re building your custom template.

Exploring Options

Click the arrow to the left of Options to open it. Then, do the same to open Item 1.

Options under Custom Project TemplateInfo.plist in Xcode

This option allows users to choose the interface type for their projects. They can choose either SwiftUI or Storyboard.

Choosing the interface type while creating a new iOS project

You want to add ViewModel.swift to the project if the user chooses SwiftUI. You’ll do that shortly.

Here’s what’s inside the Item 1 dictionary:

  • Identifier: A unique identifier to reference the option.
  • Name: The name of the option that the user will see in the New Project dialog.
  • Description: A short description of the option’s purpose.
  • Values: A list of possible values for popup type options.
  • Default: A default value in case the user doesn’t choose one.
  • Type: The type of the option, either popup, checkbox or text.

Bravo! You just finished learning the anatomy of the brain of a template. It’s time to now feed in your custom code. :]

Adding the View Model

So far, you’ve used Xcode’s Property List Editor to navigate TemplateInfo.plist. Xcode is a great way to view and tweak property lists, but it can be tough to make larger changes. Instead, you’ll edit the raw XML.

Open TemplateInfo.plist in TextEdit.app or your favorite text editor. Then, near the bottom of the file, find Values. It’ll look like this:

Interface Values in TemplateInfo.plist

Remove the Values key as well as the array under it. Replace it with this:

<key>Units</key>
<dict>
  <key>SwiftUI</key>
  <array>
    <dict>
      <key>Nodes</key>
      <array>
        <string>ViewModel.swift</string>
      </array>
      <key>Definitions</key>
      <dict>
        <key>ViewModel.swift</key>
        <dict>
          <key>Path</key>
          <string>ViewModel.swift</string>
        </dict>
      </dict>
    </dict>
  </array>
  <key>Storyboard</key>
  <dict></dict>
</dict>

Save the file and reopen it in Xcode. It will look like this:

Interface Units type in TemplateInfo.plist opened in Xcode

Here’s what’s in the items above:

  1. Units is a list of values for the option, along with the behavior for each value.
  2. Each item in the dictionary is a Value that the user will see in the New Project dialog. Currently, the values are SwiftUI and Storyboard, which are the same as the old Values.
  3. Under the SwiftUI value, there’s a dictionary for your added behavior.
  4. Nodes is a list of files that will be included if the user chooses the SwiftUI value as the option for userInterface.
  5. Definitions contains the actual path for any files in Nodes.
  6. A Storyboard value that’s the same as the one in the old Values, without any behavior.

You’re finally ready to use your template to actually create your project!