Xcode 文字巨集(Text Macros)的介紹和應用
前言
文字巨集(Text Macros
)是Xcode隱藏的特性,直到Xcode 9.0後,蘋果官方才開始允許開發者進行自定義文字巨集。下面將會詳細介紹文字巨集的相關知識和應用場景。
什麼是文字巨集
文字巨集(Text Macro
)是一種可以就地展開(expanded in-place
)為特定文字的符號。其常見於Xcode檔案模板中,如圖所示:
圖中的FILEHEADER
、FILEBASENAME
、FILEBASENAMEASIDENTIFIER
就是所說的文字巨集。Xcode在使用檔案模板建立檔案時,會把檔案模板中的文字巨集,展開生成特定的文字,如使用NSObjectObjective-C
MyObject.m
的檔案時,FILEHEADER
會展開生成頭部註釋資訊,FILEBASENAME
會展開生成字串MyObject
,FILEBASENAMEASIDENTIFIER
會展開生成字串MyObject
,如下圖所示:
延伸閱讀
Xcode模板有檔案模板和工程模板。模板檔案按照開發平臺存放,其中每個平臺的模板位置如下:
- macOS平臺模板:
/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates
- iOS平臺模板:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates
- tvOS平臺模板:
/Applications/Xcode.app/Contents/D eveloper/Platforms/AppleTVOS.platform/Developer/Library/Xcode/Templates
- watchOS平臺模板:
/Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform/Developer/Library/Xcode/Templates
公開可用的文字巨集
當前Xcode在其官方文件公開給開發者可用的文字巨集有以下幾類:
時間類:
-
DATE
當前的日期,如
2018/12/20
-
YEAR
四位數字格式的當前年數,如
2018
-
TIME
當前的時間,如
20:48
開發環境類:
-
RUNNINGMACOSVERSION
當前
macOS
系統的版本。 -
DEFAULTTOOLCHAINSWIFTVERSION
當前工程使用的
Swift
版本。 -
FULLUSERNAME
當前系統使用者的全名。
-
USERNAME
當前
macOS
使用者的登入名。
開發工程配置類:
-
ORGANIZATIONNAME
當前工程配置的公司名稱。
-
WORKSPACENAME
當前
Workspace
的名稱。如果Workspace
中只有一個Project
,那麼這個巨集的值便是當前開啟的Project
的名稱。 -
PROJECTNAME
當前工程的名稱。
-
TARGETNAME
當前
Target
的名稱。 -
PACKAGENAME
當前工程
Scheme
所設定的包名。 -
PACKAGENAMEASIDENTIFIER
把不符合
C語言識別符號規範
的字元替換為下劃線(_
)後的PACKAGENAME
。 -
PRODUCTNAME
當前工程
Scheme
設定的應用名稱。 -
COPYRIGHT
當前工程的版權資訊,如
Copyright © 2018 YK-Unit. All rights reserved.
。需要注意的是,若當前Xcode工程沒有配置公司名,該值會是一個空字串。
文字檔案資訊類:
-
FILENAME
當前檔案的完整名稱,包括副檔名。
-
FILEBASENAME
刪除掉副檔名後的
FILENAME
,如建立一個名為MyObject.m
的檔案,該值為MyObject
。 -
FILEBASENAMEASIDENTIFIER
把不符合
C語言識別符號規範
的字元替換為下劃線(_
)後的FILEBASENAME
,如建立一個名為My-Object.m
的檔案,該值為My_Object
。注:
C語言識別符號規範
只允許使用字母(A-Z
,a-z
)和數字(0-9
)以及下劃線(_
),使用這個巨集會把其他的字元自動替換成下劃線。 -
FILEHEADER
每個文字檔案頭部的文字。
注:該文字巨集其實是由多個文字巨集組成,其首先是展開生成以下文字:
// ___FILENAME___ // ___PACKAGENAME___ // // Created by ___FULLUSERNAME___ on ___DATE___. // ___COPYRIGHT___ // 複製程式碼
之後Xcode再把上述的巨集文字展開生成對應的文字,最後生成的就是我們日常看到的檔案頭部註釋資訊了。
其他:
-
NSHUMANREADABLECOPYRIGHTPLIST
macOS app
工程的target
中的Info.plist
檔案中人類可讀的版權資訊
條目的值,該值包括這個條目的key
和value
以及XML
的分隔符,如:<key>NSHumanReadableCopyright</key> <string>Copyright © 2017 Apple, Inc. All rights reserved.</string> 複製程式碼
-
UUID
使用這個巨集的時候,會返回一個唯一
ID
。具體應用場景待探索。
如何使用文字巨集
使用文字巨集的方式很簡單,只需要在文字巨集之前和之後新增三條下劃線(_
)即可,如使用FILENAME
文字巨集:
___FILENAME___
複製程式碼
如何格式化文字巨集的值
文字巨集展開生成的值,不一定符合開發要求,如建立檔案時,開發者輸入的檔名帶有非法的字元。為此,Xcode通過提供修飾符(modifier
)來對文字巨集的值進行格式化。使用修飾符的方法如下:
<MACRO>:<modifier>[,<modifier>]…
複製程式碼
文字巨集和修飾符之間用分號(:
)分隔。多個修飾符之間可以用逗號(,
)分隔。
把文字巨集和特定的修飾符結合起來後,就可以修改文字巨集的最終值,如下面這段巨集可以刪除掉的FILENAME
的副檔名以及使用下劃線(_
)替換掉不符合C識別符號
的字元:
FILENAME:deletingPathExtension,identifier
複製程式碼
這時候的
FILENAME:deletingPathExtension,identifier
等同於FILEBASENAMEASIDENTIFIER
當前Xcode提供的修飾符有:
-
identifier
用下劃線(
_
)替換所有不符合C語言識別符號規範
的字元。注:
C語言識別符號規範
只允許使用字母(A-Z
,a-z
)和數字(0-9
)以及下劃線(_
) -
bundleIdentifier
用連字元(
-
)替換所有不符合bundle識別符號規範
的字元。注:
bundle識別符號規範
只允許使用字母(A-Z
,a-z
)和數字(0-9
)以及連字元(-
)。 -
rfc1034Identifier
用連字元(
-
)替換所有不符合rfc1034識別符號規範
的字元 -
xml
將一些特殊的
XML
字元用其轉義字元替換。如,<
會被<
替換。 -
deletingLastPathComponent
從展開的字串中刪除最後一個路徑元件 (
path component
)。 -
deletingPathExtension
從展開的字串中刪除副檔名。
-
deletingTrailingDot
刪除所有句子末尾的句點(
.
) -
lastPathComponent
僅返回字元最後一個路徑元件。
-
pathExtension
返回字元的副檔名。
文字巨集的應用
從Xcode 9.0開始,開發者可以自定義文字巨集(覆蓋已有的文字巨集或者新增新的文字巨集)。但是,實際開發中,文字巨集的應用場景很少,目前暫時只發現了2個應用場景(若有其他場景,歡迎補充):
- 自定義檔案頭部註釋
- 給建立的類都新增統一字首
下面將會演示如何如何實現上述場景。
但是,在這之前,開發者需要建立一個名為IDETemplateMacros.plist
的檔案,並把檔案放置在下面檔案目錄列表中的一個:
注意:
- 不同位置具有不同的影響範圍。
IDETemplateMacros.plist
檔案可以放置到以下幾個位置中的任何一個。但是建議只放置在一個地方。- 當存在多個
IDETemplateMacros.plist
檔案時,Xcode只會使用最先找到的IDETemplateMacros.plist
。
-
Project user data
位置:<ProjectName>.xcodeproj/xcuserdata/[username].xcuserdatad/IDETemplateMacros.plist
影響範圍:對當前 Project 指定的使用者(username)建立的檔案有影響
-
Project shared data
位置:<ProjectName>.xcodeproj/xcshareddata/IDETemplateMacros.plist
影響範圍:對當前 Project 的所有成員建立的檔案有影響
-
Workspace user data
位置:<WorkspaceName>.xcworkspace/xcuserdata/[username].xcuserdatad/IDETemplateMacros.plist
影響範圍:對當前的 Workspace 下的指定的使用者(username)建立的檔案有影響
-
Workspace shared data
位置:<WorkspaceName>.xcworkspace/xcshareddata/IDETemplateMacros.plist
影響範圍:對當前 Workspace 下的所有成員建立的檔案有影響
-
User Xcode data
位置:~/Library/Developer/Xcode/UserData/IDETemplateMacros.plist
影響範圍:對當前 Xcode 建立的檔案都有影響
自定義檔案頭部註釋
Xcode檔案模板中,使用FILEHEADER
文字巨集來展開生成頭部註釋,所以只需要在IDETemplateMacros.plist
中重定義FILEHEADER
即可。編輯後的IDETemplateMacros.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>FILEHEADER</key>
<string>
// __ _,--="=--,_ __
// / \." .-. "./ \
// / ,/ _ : : _ \/` \
// \ `| /o\ :_: /o\ |\__/
// `-'| :="~` _ `~"=: |
// \` (_) `/
// .-"-. \ | / .-"-.
//.------------------{ }--| /,.-'-.,\ |--{ }-----------------.
// ) (_)_)_) \_/`~-===-~`\_/ (_(_(_) (
//
// File Name: ___FILENAME___
// Product Name: ___PRODUCTNAME___
// Author: ___AUTHOR___
// Swift Version: ___DEFAULTTOOLCHAINSWIFTVERSION___
// Created Date: ___DATETIME___
//
// Copyright © ___YEAR___ ___ORGANIZATIONNAME___.
// All rights reserved.
// ) (
//'--------------------------------------------------------------------'
</string>
<key>AUTHOR</key>
<string>[email protected]___ORGANIZATIONNAME___</string>
<key>DATETIME</key>
<string>___DATE___ ___TIME___</string>
</dict>
</plist>
複製程式碼
注意:示例中不止是重定義
FILEHEADER
,還新增了新的文字巨集AUTHOR
和DATETIME
。
這時候使用Xcode建立的文字檔案的頭部註釋如下:
註釋中的
dog
圖形是使用命令列字元形狀工具boxes
生成。
boxes
支援建立各種字元形狀,有興趣的童鞋不妨去探索下。
給建立的類都新增統一字首
Xcode檔案模板中,使用FILEBASENAMEASIDENTIFIER
文字巨集來展開生成類名,所以只需要在IDETemplateMacros.plist
中重定義FILEBASENAMEASIDENTIFIER
即可。編輯後的IDETemplateMacros.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>FILEBASENAMEASIDENTIFIER</key>
<string>YK___FILENAME:deletingPathExtension,identifier___</string>
</dict>
</plist>
複製程式碼
這時候使用Xcode建立的一個類時,類的字首都是以YK
開頭,如圖所示: