Xcodeのカスタムテンプレートを作成して他のMacと共有する
M1 MacBook Airのバッテリーの持ちが良いので最近はあちこち移動しながらMacBook Airで作業をすることが多くなった。そこでXcodeのカスタムテンプレートも共有したいと思ったので、作成方法も合わせてメモをしておく。
テンプレートの場所
Xcodeのテンプレートは以下の場所にある。
/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/
ここにはFile Templates
とProject Templates
の2つのフォルダがあるが、それぞれフォルダ名の通りファイルのテンプレートとプロジェクトのテンプレートが入っている。
File Templates
の中には新規ファイル作成時に表示されるダイアログのカテゴリ毎にフォルダがあり、その中にファイルのテンプレート1つづつのフォルダが保存されている。
が、カスタムテンプレートはユーザ毎に~/Library/Developer/Xcode/Templates
に入れる方が他のMacとの共有やXcodeのアップデートを考えると良いだろう。
下記はまだTemplates
フォルダを作成していないユーザのXcode
フォルダの内容。
カスタムテンプレートのフォルダ構造
Templates
以下のフォルダ構造は下記のようになってる。ここではサンプルとしてMetalCIFilter
カスタムテンプレートを使って説明する。
-
MetalCIFilter
フォルダTemplates
フォルダ直下のフォルダはファイル作成時に表示されるダイアログでのカテゴリ。ここではMetalCIFilter
がカテゴリ名になる。ちなみにSource
などの既存のカテゴリ名のフォルダを作成した場合はそのカテゴリ内に表示される。 -
MetalCIFilter.xctemplate
フォルダ 作成するカスタムテンプレートのファイル群を入れるフォルダで拡張子が.xctemplate
となる。
XcodeでNew File...
を実行した時に表示されるダイアログではこうなる。
下記3種類がこのサンプルのカスタムテンプレートを構成するファイル。
-
___FILEBASENAME___.metal
,___FILEBASENAME___.swift
これはソースファイルのテンプレート。___FILEBASENAME___
がファイル作成時に入力したファイル名に置き換わってソースファイルが作成される。例えばファイル作成時にMyFilter
を入力するとMyFilter.metal
とMyFilter.swift
が作成される。 -
TemplateIcon.png
とTemplateIcon@2x.png
これはファイルのアイコン画像。
-
TemplateInfo.plist
カスタムテンプレートのプロパティを設定するプロパティファイル。詳細は下記。
カスタムテンプレートを作成する
説明したカスタムテンプレートを構成するファイルのうち自分で作成する必要があるのはテンプレートファイルとTemplateInfo.plist
。アイコンは既存のものをコピーして使って問題ない。(もちろん自作のアイコンを作っても良い。)
___FILEBASENAME___.metal
このファイルが作成されるファイルのテンプレートとなる。___FILEBASENAME___.metal
は以下のような内容になっている。
//___FILEHEADER___
#include <metal_stdlib>
using namespace metal;
#include <CoreImage/CoreImage.h>
extern "C" { namespace coreimage {
float4 ___VARIABLE_funcName:identifier___(sample_t s) {
return s;
}
}}
___FILEHEADER___
は新しいファイルを作成した時に現れるプロジェクト名やコピーライトなどが表示されるテンプレートタグ。1行書いておけば全て表示される。
___VARIABLE_funcName:identifier___
は後述するプロパティファイルで設定された変数funcName
を使用するテンプレートタグ。例えばこの場合funcName
にmyFunc
が割り当てられると下記のように展開される。
float4 myFunc(sample_t s) {
___FILEBASENAME___.swift
も基本的に同じように展開/作成される。
TemplateInfo.plist
カスタムテンプレートのプロパティを設定するファイル。MetalCIFilter
のTemplateInfo.plist
は以下のような内容になっている。
<?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>AllowedTypes</key>
<array>
<string>com.apple.metal</string>
</array>
<key>Platforms</key>
<array>
<string>com.apple.platform.iphoneos</string>
<string>com.apple.platform.macosx</string>
</array>
<key>DefaultCompletionName</key>
<string>File</string>
<key>Description</key>
<string>A CIKernels in Metal shader source file.</string>
<key>Kind</key>
<string>Xcode.IDEFoundation.TextSubstitutionFileTemplateKind</string>
<key>MainTemplateFile</key>
<string>___FILEBASENAME___.metal</string>
<key>Summary</key>
<string>A CIKernels in Metal shader source file</string>
<key>SortOrder</key>
<string>50</string>
<key>Options</key>
<array>
<dict>
<key>Identifier</key>
<string>funcName</string>
<key>Required</key>
<true/>
<key>Name</key>
<string>Function Name:</string>
<key>Description</key>
<string>The name of the function in Metal Shader.</string>
<key>Type</key>
<string>text</string>
<key>Default</key>
<string>myMetalShaderFunc</string>
</dict>
<dict>
<key>Identifier</key>
<string>resourceName</string>
<key>Required</key>
<true/>
<key>Name</key>
<string>Resource Name:</string>
<key>Description</key>
<string>The name of the Metal resource.</string>
<key>Type</key>
<string>text</string>
<key>Default</key>
<string>myMetalShader</string>
</dict>
</array>
</dict>
</plist>
プロパティの説明
- AllowedTypes ファイルのUTI情報
- Platforms テンプレートを使用できるプラットフォームを表す配列。空の場合すべてのプラットフォームで使用できるようになる。指定する場合は
com.apple.platform.iphoneos
のようにプラットフォームを指定する。 - DefaultCompletionName テンプレート選択時の最後に入力するファイル名のデフォルト値
- Description テンプレートの説明文
- Kind テンプレートであることを示す値。
- MainTemplateFile 複数のファイルがテンプレートによって作成される場合、テンプレート作成後にどのファイルを選択するか指定する。
- Summary テンプレートの説明文
- SortOrder カテゴリ内での表示順の値
Options
以下
ユーザからの入力を要求するプロパティの辞書が配列に入っている。この例では2つのユーザ入力を使用している。
- Identifier ユーザからの入力を収めるプロパティ(変数)のID。
string
で名前をfuncName
としている。上記___FILEBASENAME___.metal
内の___VARIABLE_funcName:identifier___
はこのプロパティ(変数)で入力された値が使用される。 - Required 入力が必須かどうかの論理値。必須とした場合入力をしないとファイル作成時に
Next
ボタンがグレーになって先へ進めない。 - Name 入力部分のラベルに表示する名称。この例ではテキストボックスの左に表示される文字列。
- Description 入力の説明。上記
Name
などの上にマウスカーソルを置くと表示される。 - Type 入力のタイプ。この例ではテキスト。
- Default 入力値のデフォルト。文字列の入力の場合テキストボックスに入力された状態で表示される。
表示されるユーザ入力のダイアログは以下のようになる。
カスタムテンプレートを共有する
カスタムテンプレートを~/Library/Xcode/Templates
に作成したら後はiCloudにリンクを張って他のMacと共有する。これはカスタムスニペットの時と同じ。
手順としては、テンプレートを作ったMacでユーザフォルダ内に作成したTemplates
フォルダをiCloudに移動してiCloudへのリンクを張る。
mv ~/Library/Developer/Xcode/Templates ~/Library/Mobile\ Documents/com\~apple\~CloudDocs/XcodeDocs
ln -s ~/Library/Mobile\ Documents/com\~apple\~CloudDocs/XcodeDocs/Templates ~/Library/Developer/Xcode
後はそれぞれのMacの~/Library/Developer/Xcode
フォルダからiCloudのTemplates
へリンクを張ればOK。
サンプル
今回サンプルで作ったMetalCIFilterテンプレートはGitHubに置いてある。
最後に
スニペット、テンプレートと来たので次はプロジェクトといきたいところだが、まだ必要だと感じる状況ではないのでひとまずはここまで。
それよりもAndroid StudioがM1 Macで動くようになったらしいのでそちらが気になる…。
Discussion