Creating Custom Xcode 4 Project Templates

December 5th, 2011

Filed under: Xcode | 22 comments

This post contains the material on custom project templates I had prepared for the book. The material was not strong enough to put in the book, mainly because creating custom project templates manually in Xcode 4 is difficult (much more difficult than in previous versions of Xcode) and not documented by Apple. I had a difficult time getting a simple project template to work. But there is not a lot of information available on creating Xcode 4 project templates so I’m making what I wrote available here. I hope it helps you create your own project templates.

For more information on Xcode 4 project templates, look at Apple’s templates and read the following articles, which you’ve probably read if you’ve done a Google search for creating project templates in Xcode 4:

A minimal project template for Xcode 4

About XCode 4 Project Template (How To Create Custom Project Template)

Project Template Contents

At a minimum a project template consists of two items: a folder with the extension .xctemplate and a property list file named TemplateInfo.plist. You can also have additional files like icon files, source code files, and xib files in the project template. Place these files and the property list file in the template folder.

The .xctemplate extension defines the folder as a template folder. The name of the folder is the name that appears in the list of templates for the selected category in the New Project Assistant. The name of the folder is the name of the template.

Apple’s Project Templates

I recommend duplicating the TemplateInfo.plist file from one of Apple’s templates and using that copy as your TemplateInfo.plist file. You can find Apple’s iOS project templates in the following location:

Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/Project Templates

The rest of Apple’s project templates are in the following location:

Developer/Library/Xcode/Templates/Project Templates

Developer is where you installed Xcode 4. For Xcode 4.3 and later you can find Apple’s project templates in the Xcode application bundle. Select the Xcode application in the Finder, right-click, and choose Show Package Contents to access the files in the application bundle.

Open the TemplateInfo.plist file in Xcode to modify it. I’m going to cover the keys in the TemplateInfo.plist file later in this post.

Moving the Template Folder

For Xcode to find your project template you must move the template folder to the user templates folder, which is in the following location:

/Users/Username/Library/Developer/Xcode/Templates/Project Templates/GroupName

You may need to manually create some of the folders in the path to the user templates folder. GroupName is the name of the category on the left side of the New Project Assistant. You can create your own group name or use one of the built-in names. Your project template will appear in the GroupName category.

TemplateInfo.plist Keys

The TemplateInfo.plist file has the following keys (this may not be an exhaustive list) for project templates:

  • Ancestors
  • Concrete
  • Definitions
  • Description
  • Identifier
  • InjectionTargets
  • Kind
  • MacOSXVersionMin
  • Nodes
  • Options
  • Platforms
  • Project
  • SortOrder
  • Targets

Your template does not have to use all these keys. The data type for the keys is usually one of the following: Array, Boolean, Dictionary, or String.

Ancestors Key

The Ancestors key is an array of strings. The strings are the identifiers of the project templates your template inherits from. If your template has no ancestors, you can ignore this key.

Suppose your template inherits from Apple’s Cocoa Application template. You want the same options the Apple template has to create a document-based application, to use Core Data, and to add a unit testing bundle. In this case you would need to inherit from Apple’s document-based application, Core Data application, and CoreDataSpotlight application templates. You would add the following ancestor values to your template:

com.apple.dt.unit.cocoaDocumentBasedApplication
com.apple.dt.unit.coreDataApplication
com.apple.dt.unit.coreDataSpotlightApplication

Concrete Key

The Concrete key is a Boolean value. You must set the Concrete key to YES for your template to appear in the New Project Assistant.

Definitions Key

The Definitions key is a dictionary. This key allows you to add comments, includes, and code to source code files. It also allows you to create groups from files or folders in an Xcode workspace. If you use the Definitions key to create groups, you must also have a Nodes key in your project template.

Description Key

The Description key describes the project template. The contents of the Description key appear at the bottom of the New Project Assistant when you select the project template.

Identifier Key

The Identifier key is a string value that uniquely identifies your template. It takes the following form:

com.CompanyName.TemplateName

InjectionTargets

The InjectionTargets key is an array of strings. The strings are the identifiers of project templates. The InjectionTargets key is a new key, which didn’t exist when I originally researched custom project templates. A Google search turned up no results. You’re on your own.

Kind Key

The Kind key is a string value. It should have the following value:

Xcode.Xcode3.ProjetTemplateUnitKind

If you inherit from another template, you shouldn’t have to specify the Kind key.

MacOSXVersionMin Key

The MacOSXVersionMin key is the earliest version of Mac OS X that can use the template.

Nodes Key

The Nodes key is an array key that creates a file in the project. Add a string key for each file you want to be created in the project. The value for the key is the name of the file.

Options Key

The Options key is an array that lets you add controls to the New Project Assistant. An example of a custom control is the Type pop-up menu for command-line tool projects that lets you choose the language for the project. The Type menu is an example of a custom control.

Create a dictionary key for each control you want to add. Add keys to the dictionary key. The following are common keys for controls:

  • Type identifies the type of control. Pop-up menus should use a value of popup. Checkboxes should use a value of checkbox. Text fields should use a value of text. Combo boxes should use a value of combo.
  • Name is the label for the control.
  • Description contains tool tip text for the control.
  • Identifier is a string that uniquely identifies the control.
  • Default is a string that provides a default value for a control.
  • Values is an array that contains the entries for a combo box or pop-up menu.
  • Required is a Boolean key that says whether a condition has to be true for the control to be enabled.

You can see an example of the Required key if you create a Cocoa application. The Document Extension text field is disabled unless you select the Create Document-Based Application checkbox. If you use the Required key, you must add a RequiredOptions dictionary key that contains the conditions.

Platforms Key

The Platforms key is an array of strings that identifies the platforms the template works on. A Mac project template has the following value:

com.apple.platform.macosx

An iOS project template has the following value:

com.apple.platform.iphoneos

Project Key

The Project key is a dictionary key that contains build settings. For those of you creating project templates for personal use, I recommend using a configuration settings file instead of placing build setting values in the project template. A reason to add build settings is if you want to add libraries to the project template. Add a build setting for linker flags and add the flags for the libraries, such as -lLibraryName.

If you use the Project key to place build settings in the project template, you will most likely need to create additional dictionary keys inside the Project key. Create a Configuration dictionary key for configuration-specific build settings. Inside the Configurations dictionary, create Debug and Release dictionaries. Place your configuration-specific build settings inside the Debug and Release dictionaries. Create a SharedSettings dictionary for any build settings that apply to all build configurations. Place any build settings that apply to all build configurations inside the SharedSettings dictionary.

SortOrder Key

I’m not exactly sure what the SortOrder key does. I haven’t seen a sort order value other than 1 in Apple’s templates.

Target Key

The Targets key is an array key you use to add frameworks, libraries, build phases, and build settings to the template. The build settings you add to the Targets key apply to the target while the build settings you add to the Project key apply to the project.

To add frameworks to the template, add a Frameworks key to the Targets key. The Frameworks key should be an array. Add string keys to the Frameworks key. The value of a string key is the name of the framework. None of Apple’s project templates use a library so I don’t know what you have to do to add a library to the Target key.

To add build phases, create a dictionary key named BuildPhases. Add a dictionary key for each build phase you want in the project template. At a minimum you need to add a Class string key to the dictionary key that contains the name of the build phase. Use the following values:

  • Sources is the name for the Compile Sources build phase.
  • Frameworks is the name for the Link Binary with Libraries build phase.
  • Resources is the name for the Copy Bundle Resources build phase.
  • CopyFiles is the name for the Copy Files build phase.
  • ShellScript is the name for the Run Script build phase.
  • Headers is the name for the Copy Headers build phase.
  • Rez is the name for the Build Carbon Resources build phase.

Tags:


22 thoughts on “Creating Custom Xcode 4 Project Templates

  1. Bochun Zhu says:

    Thank you so much for your info. My Xcode does not diplay iOS project templates but only Mac OS X project tempplates.

    Then I follow your instructio:
    1. Under Macintosh HD, create folder /Users/Username/Library/Developer/Xcode/Templates/Project Templates/GroupName, where both Username and GroupName are relavent to user, for my case, I use “Staff EEE” and myiOS respectively
    2. copy folder iPhone Base.xctemplate from Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/Project Templates to /Users/Staff EEE/Library/Developer/Xcode/Templates/Project Templates/myiOS
    3. restart Xcode, it still cannot show iOS project template. My Xcode version is 4.2, Mac OS X version is 10.7.3

    If I can locate original iOS project template folder, why my Xcode can only show Mac OS X project template? I’ve strugged for a few days. No any progress at all.

    Your kindly advice would be very much appreciated.

    Ms. Zhu

    • Mark Szymczyk says:

      Bochun Zhu,

      The most likely reason the template is not appearing in the New Project Assistant is the template you duplicated, the iPhone Base template, is an abstract template. For a template to appear in the New Project Assistant, the Concrete key must be set to YES. Duplicate another template, such as one of the iOS application templates, and see if that works.

  2. Ranga Reddy says:

    Hi, this is pretty useful stuff, really thanx for your efforts.

    Is it possible that we add something in template-info.plist ( which is in Custom template) and that should get reflected in project-info.plist which is created using this Custom template.

    IF YES

    Can you Please Suggest me in-detail what keys do we need to use in-order to reflect the changes and what are scalar types( like array, dict, strings, BOOL) that needs to be used in this process.

    Thanks in-advance to someone who responds to this post.

    • Mark Szymczyk says:

      Ranga,

      If you want something to be added to project-info.plist, I suggest supplying your own plist file with the project template. Copy one of Apple’s project-info.plist files, modify it to suit your needs, and add it to the project template folder, the folder with the .xctemplate extension. Use the Nodes key in TemplateInfo.plist to tell Xcode to create the plist file you are supplying.

      For more information on property lists, read the Property List Programming Guide, which is part of Apple’s documentation.

  3. mikki says:

    hi, finally a clear article on Templates…especially for 4.3. given the contradicting stuff out there.

    I have a question on the Project Template.
    I made a copy of a Project Template for me to work with. I can create a new Project with my customized template (the changed ‘description’ key verifies it).
    But how do I change the header text in the myAppDelegate.h and myAppDelegate.m files that are created with the Project?
    ideas?

    • Mark Szymczyk says:

      Mikki,

      I’m not sure what you mean by “change the header text in the myAppDelegate.h and myAppDelegate.m files”. If you want to customize the text that appears in the .h and .m files, go to the folder where your custom project template is. Open the .h and .m files in Xcode and modify them to suit your needs.

  4. Jon says:

    Any thoughts on why an Option defined with an Identifier of apiToken of type text would strip off the first character and replace it with _ if that character is a number when using ___VARIABLE_apiToken:identifier___?

    Examples:

    user enters “123abc”, ___VARIABLE_apiToken:identifier___ yields “_23abc”
    user enters “abc123”, ___VARIABLE_apiToken:identifier___ yields “abc123”

    —-
    preemptive answer: the :identifier part of ___VARIABLE_apiToken:identifier__ appears to invoke some rules engine that ensures that the string is a valid variable name. if you leave it off ___VARIABLE_apiToken___ then you get the expected result.

    great article.

    • Mark Szymczyk says:

      Jon,

      I don’t have an explanation for you. It’s been a while since I’ve tried to do anything with custom project templates.

  5. P says:

    Jon,

    I’m running into the same exact problem and can’t figure it out either. It is the case not only on my custom project templates, but also Apple’s defaults (try, for example, naming your Single View Project “123abc”).

    I’ve got a great little template going here, but can’t solve this one problem 🙂

    (BTW, great article Mark!)

    –P

  6. Rei Vilo says:

    Thanks for the explanation on ___VARIABLE_…:identifier___

  7. Peter Jiang says:

    Thank you very much for your info.
    Then I have a question,how to set the dynamic link library in the TemplateInfo.plist?Now, I can set the framework in Targets->Item0->Frameworks, for example,add the SystemConfiguration, then auto add the SystemConfiguration.framework in the project.But add the libsqlite3.dylib,then the project has a error.
    Thank you.

    • Mark Szymczyk says:

      Peter,

      My only experience with custom project templates involved adding frameworks to the project template, not dynamic libraries. It’s been over a year since I tried to create a custom project template so I don’t have a solution for you.

  8. ??? says:

    I created a project template file – TemplateInfo.plist which is defined with ARC usage. There are a few external files which I included in the template that are not ARC supported. In a regular project I would set manually the compiler flags for those files in build phases-> compile sources to -fno-objc-arc but how can I do it inside the template? I didn’t find anything related.. any idea?

    Thanks

    • Mark Szymczyk says:

      I have not tried setting per-file compiler flags in a project template. After re-reading my original post, I can think of one possible idea. Add a Target key. For the target add a BuildPhases dictionary key. Add a Sources key that corresponds to the Compile Sources build phase. Add the external files without ARC support to the Compile Sources and add the -fno-obj-arc flag there.

  9. zhuo says:

    Compile sources

  10. […] TemplateInfo.plist????????????????????? […]

  11. PARVEZ QURESHI says:

    I would like to incorporate multiple configurations like “QA”, “Development”, “Production” as described in link
    http://code.tutsplus.com/tutorials/ios-quick-tip-managing-configurations-with-ease–mobile-18324

    but I want these configurations incorporated inside the project template. I have modified the project template’s TemplateInfo.plist file’s Project and Targets keys to contain these additional configurations. These configurations are visible in target build settings in the project created using the template.
    Problem How can these configurations be made available as part of scheme using the template so that we can select a particular configuration and run the application.

    • Mark Szymczyk says:

      Parvez,

      I do not have a solution for you. I have not worked with Xcode project templates in years. All my knowledge of Xcode project templates is in the article.

  12. Parvez Qureshi says:

    Thanks Mark for the reply.
    Will xcconfig file be of any help in this regard ? Any idea ?

    • Mark Szymczyk says:

      An xcconfig file is not going to help. Xcconfig files will not make custom build configurations appear in Xcode’s scheme editor.

      Xcconfig files contain a list of build settings and values. You use xcconfig files when you find yourself overriding the values of the same Xcode build settings in your projects. You would place the build settings you want to override in the xcconfig file to avoid having to change them in Xcode for every project.

  13. parvez qureshi says:

    I have pre created configuration based xcscheme files like QC.xcscheme from the information given on link http://www.rubydoc.info/gems/xcodeproj/Xcodeproj/XCScheme. I placed all these xcscheme files in the directory containing Templateinfo.plist file. Then added entries in Nodes and Definitions section in Templateinfo.plist file related to these xcscheme files. The relevant schemes are generated but they are poiting to “My Mac” instead of ios simulators/ios device. Looking further into this. If you see anything unusual then plz do let me know.

Leave a Reply to Mark Szymczyk Cancel reply

Your email address will not be published. Required fields are marked *