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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Xcode Project and File Templates
30 mins
- Getting Started
- Understanding Default Templates
- Exploring Base Templates
- Exploring iOS Templates
- Creating Your First Project Template
- Contents of a Template
- Customizing the Project Template
- Working With Project Template Info
- Exploring Options
- Adding the View Model
- Using the Template
- Populating the Project
- Creating File Templates
- Copying a Default File Template
- Customizing the File Template Info
- Creating Template Files
- Using the Template
- Finishing the Project
- Where to Go From Here?
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
This command creates an empty ViewModel.swift file within your 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.
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
andcom.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 tofalse
, 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. UsingOptions
, you can ask the user for input in the form of text fields, checkboxes and drop-down lists. Additionally, theOptions
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.
This option allows users to choose the interface type for their projects. They can choose either SwiftUI or Storyboard.
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
ortext
.
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:
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:
Here’s what’s in the items above:
-
Units
is a list of values for the option, along with the behavior for each value. - 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 oldValues
. - Under the SwiftUI value, there’s a dictionary for your added behavior.
-
Nodes
is a list of files that will be included if the user chooses the SwiftUI value as the option foruserInterface
. -
Definitions
contains the actual path for any files inNodes
. - A
Storyboard
value that’s the same as the one in the oldValues
, without any behavior.
You’re finally ready to use your template to actually create your project!