read

If you use Swift Package, there are 2 pesky problems whenever you create a new file.

Problem 1: No header template

It creates a new file WITHOUT package name and organization copyrighty stuff.

Oh gosh. How empty.

Solution: Workspace Header Template

This solution only works if you have a workspace containing the Swift Package.

Create IDETemplateMacros.plist and place it in

  • MyModule.xcworkspace/xcshareddata/IDETemplateMacros.plist

A standard plist will look like the following. Change the macros as needed.

<?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>ORGANIZATIONNAME</key>
	<string>Just2us</string>
	<key>PACKAGENAME</key>
	<string>DaSwift</string>
	<key>FILEHEADER</key>
    <string>
//  ___FILENAME___
//  ___PACKAGENAME___
//
//  Created by ___FULLUSERNAME___ on ___DATE___.
//  Copyright © ___YEAR___ ___ORGANIZATIONNAME___. All rights reserved.
//</string>
</dict>
</plist>

Problem 2: No prompt for filename

With the custom header template, things will look much better. Yet there is one other weird behaviour.

Somehow, only for Swift Package, Xcode will never ask for the filename!

It will be created as “File.swift”. Then we dev have to waste our time renaming the file, and also correct the name in header!

Solution: Xcode Template

The problem lies with Xcode default template. It is configured that way for Swift package files. You can see the template definition in
/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/File Templates/MultiPlatform/Source/Swift File.xctemplate/TemplateInfo.plist.

I wrote about custom file templates in 2017.

We can use it to write a Better Swift template.

Create the following directory:

  • ~/Library/Developer/Xcode/Templates/File Templates/Source/Better Swift.xctemplate/

It needs 2 files.

The first is ___FILEBASENAME___.swift, with the content,

//___FILEHEADER___

import Foundation

That’s how the string from IDETemplateMacros.plist is appended to the template. You can adjust them to your workflow. 🚀

The 2nd file is TemplateInfo.plist, with this content,

<?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>SupportsSwiftPackage</key>
	<true/>
	<key>Kind</key>
	<string>Xcode.IDEFoundation.TextSubstitutionFileTemplateKind</string>
	<key>Description</key>
	<string>An empty Swift file.</string>
	<key>Summary</key>
	<string>An empty Swift file</string>
	<key>SortOrder</key>
	<string>1</string>
	<key>Image</key>
	<dict>
		<key>FileTypeIcon</key>
		<string>swift</string>
	</dict>
	<key>AllowedTypes</key>
	<array>
		<string>public.swift-source</string>
	</array>
    <key>Platforms</key>
    <array />
	<key>DefaultCompletionName</key>
	<string>File</string>
	<key>MainTemplateFile</key>
	<string>___FILEBASENAME___.swift</string>
	<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>
	</array>
</dict>
</plist>

My plist above added the Options key-value (the rest are the same copied from the Xcode template).

With that, whenever you create a new file, choose Better Swift.

If you’re curious how that options change everything, read the post on the productName identifier.


Image

@samwize

¯\_(ツ)_/¯

Back to Home