在 Xcode 中自定义快捷模板(Template)

日常开发中,我们每次新增一个模块时,在创建模块各部分文件的操作上总是重复的,创建View,Model,ViewModel,VC,还要设定相关参数。这类操作可以用 Xcode 的模板来简化。

模板生成示例

【模板?为什么要自定义模板?】

在开发中,模板是将一个事物的结构规律予以固定化、标准化的成果,它体现的是结构形式的标准化。就像我们自定义的“快捷代码”,它也是模板。本文主要介绍 Xcode 中创建模块时使用的模板(Templates)。

Xcode系统模板面板.png

开发中每天与模板相伴,上图是 Xcode 提供的系统模板,这些模板帮助我们更快的创建对应的模块,以 ViewController 为例:

Xcode创建模板

在创建面板上只需要设定好”名称“、”基类“、”是否要生成对应的XIB文件“,系统就会自动为我们创建好这些文件,命名好相关的类,关联好 XIB 与 ViewController 。模板将自动完成这些,如果我们单独进行操作,将会一次又一次为此消耗掉不少时间。

系统提供的模板都是最最基础的,在日常开发中,项目模块的架构都会有一定规律可循,无论是什么结构(MVC/MVVM/MVP),都可以通过 Xcode 的自定义模板来避免重复创建Model、ViewModel、View(甚至更多)的情况发生。


【系统的模板】

开始创建自定义模板之前,先了解下系统的模板是什么样的。系统模板路径为:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates

可以看到这里分为”文件模板“”项目模板“,项目模板是我们创建项目时使用的(如 Single View App、各种 Extension 等等),这里不讨论。我们主要看文件模板,文件模板中种类繁多,这里主要看 “Cocoa Touch Class.xctemplate”,完整路径为:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File Templates/Source/Cocoa Touch Class.xctemplate

这个是CocoaTouch相关的模板,例如上面提到的 ViewController 。

模板文件

以 UIViewControllerXIBSwift 为例,当语言为Swift,基类为 UIViewController,并勾选了生成XIB时,Xcode就会根据此模板生成对应的文件。可以看到模板中有两个文件:

Xcode系统模板文件ViewController

Xcode会根据这两个文件为模板生成我们的 ViewController 及关联的 XIB 文件。

可以看到,两个文件名都为 __FILEBASENAME__,这里就要提到模板中的,宏在Xcode创建模板时会被替换成对应的值(无论是文件名,还是文件内部),此处的 __FILEBASENAME__ 在创建模板后会被替换成设置的文件名。更多的宏可查阅官方文档

模块配置文件 TemplateInfo.plist

系统模板配置文件

系统模板中这些配置字段的含义如下:

  • Kind: 模板类型
    此处固定为 Xcode.IDEFoundation.TextSubstitutionFileTemplateKind,还有 CoreData 相关的Xcode.IDECoreDataModeler.ManagedObjectTemplateKind,本文不做介绍
     
  • Description: 描述文字
    Xcode早期版本创建模板时可以看到描述文字,现在的版本默认不显示(有说创建时双击可显示,老夫双击烂了也没反应)
     
  • Summary: 简要文字
    与 Description 一样,是对模板的介绍文字。
     
  • SortOrder: 排序优先级
    在模板面板中排序的优先级
     
  • DefaultCompletionName: 默认文件名
    默认文件名是在保存文件对话框中文件的默认名称
     
  • Platforms: 模板所支持的环境
    模板会出现在包含的环境所对应导航栏下,相关环境字段如下:
    com.apple.platform.macosx
    com.apple.platform.iphoneos
    com.apple.platform.watchos
    com.apple.platform.appletvos

     
  • Options: 模板选项
    Options 是一个集合,配置创建模板的面板相关属性,如名称,类型,选项卡,选项约束等。模板中的宏会被此处的配置值替换
系统模板配置文件Options展开

Options 中有四个配置选项,通过 Name 等描述字段可知分别是“类名”、“基类名”、“是否创建XIB”、“语言选取”。

常见字段介绍:
identifier
模板选项的唯一标识,我们在模板文件中可以通过宏来引用它的值。
也就是说它也用来保存模板选项的值。例如系统 Viewcontroller 模板文件中引用创建模板时开发者设定的基类名使用了:
___VARIABLE_cocoaTouchSubclass___
这里的 ___VARIABLE_XXXXXX___ 也是宏,紧跟着的 cocoaTouchSubclass 是第二个 option 的 identifier 的值。
 
Type:
选项类型。ViewController 中类型为text(手动输入),基类为class(类选取)创建XIB为checkbox(勾选框),语言选取为popup(弹框)。
 
Values:
某类值的集合。这个值跟当前选项具体内容有关,最直观的就是语言选项中的Values就是用户可以选择的两种开发语言Objective-C与Swift。
Default:
选项默认值。这个跟选项类型有关,例如 checkbox 类型的创建XIB选项默认创建,其值就为false,语言选择是必选的,其默认值就为Objective-C。
 
RequiredOptions:
必要选项,字面是这个意思,从XIB选项中可以看出,这个字段是与checkbox 配合的,当基类出现指定的值时,勾选框就可选。
&nbsp

很多字段没有一一列出,可以自行尝试修改去理解其含义和使用方法,不过最好还是不要更改系统模板,可以将系统模板复制一份或者拷贝一份到我们自定义的模板中。

自定义模板的路径为:
/Library/Developer/Xcode/Templates/File Template/Custom/
默认情况下是没有 Templates 文件的,自己创建就好,将系统模板(Cocoa Touch Class.xctemplate)整个拷贝到这里,最好自己改个名字方便理解(如:SysCopy.xctemplate)。

拷贝过来后,在Xcode中创建模板时就会看到多了一个 "Custom" 栏,里面正好是拷贝并重命名后的系统模板:

系统拷贝模板

现在就可以任意凌虐这份拷贝后的模板了。

【小结】:
由上可以看出 Xcode 的模板文件根据其配置文件与开发者交互来定制化输出对应的文件。


【自定义模板】

以 MVC/MVVM 为例,每个模块都需要重复配置 View,Model,ViewController,XIB等文件,现在尝试通过自定义模板来简化重复的操作,每次只需要输入模块名称即可。

1.创建模板

1)在/Library/Developer/Xcode/Templates/File Template/Custom/路径下创建模板文件 RJMVVM.xctemplate
2)在 RJMVVM 模板文件中创建配置文件 TemplateInfo.plist,为了方便建议直接拷贝系统配置文件。

为了精简,本文示例只留下了必要字段与一个模块名输入框。

自定义模板的配置plist.png

效果如下:

自定义模板单行输入框

此时创建模块就可以在 Xcode 模板创建面板中看到 RJMVVM 选项,不过现在创建后没有任何反应。

2.创建文件

在 RJMVVM.xctemplate 模板文件内创建 ViewController 的模板。以 ViewController 文件为例:

// MyVC.swift
import UIKit
class MyVC: MyBaseVC {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

// 各种业务   
extension MyVC {

}

现在再创建模块的话,Xcode 会将 MyVC.Swift直接复制到项目中。同样的,我们可以将View,Model,ViewModel 等需要制作成模板的文件也添加到模板文件中。

3.利用宏关联文件

在第二步中,模板只是简单地将相关文件拷贝到了项目中,输入的模块名想要关联到文件名、类名等需要用到系统所提供的宏。上面提到的“___VARIABLE_XXXXXXX___”就是一种宏,用来获取配置文件中的值。要获取模块的名称需要用到的是"___FILEBASENAME___"

这里要特别注意的是,__FILEBASENAME__options中的 productName 选项派生的,所以,要使用这个宏,就不能更改 productName,否则宏无法关联到我们输入的名称,其默认将会使用 DefaultCompletionName 字段的值。

不仅仅是文件名,还有代码中的类名,基类名,协议等都可以进行关联,此处以类名为例(毕竟本例只有一个输入框),我们直接用文件名的命名方法来修改相关类的名称,不过此处用到的宏是___FILEBASENAMEASIDENTIFIER___,以 ViewController 模板为例进行修改

// VC
// 此处的 ___FILEBASENAMEASIDENTIFIER___ 与文件名相同
class ___FILEBASENAMEASIDENTIFIER___: MyBaseVC {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
}

extension ___FILEBASENAMEASIDENTIFIER___ {
    
}

此时再去创建模板的话,ViewController 的文件就会根据输入的名称去修改替换模板文件名称中的宏及其代码中的宏。

ViewController 替换

至此,一个最最简单的模板就完成了,不用每次创建新模块都要花几分钟来配置文件结构。


【 Do you want know more ? 】

如何关联 XIB 文件?

与一般文件相同,将XIB文件放入模板文件中,并利用宏配置其名称,创建模板时将自动创建相关的XIB文件。这里要注意的是,XIB 文件基本都是与 VC 进行绑定的。我们直接将系统模板的XIB文件打开看看:

XIB关联

注意图中红框部分,xib的类这里用到了宏,也就是说模板会将XIB跟宏所代表的类关联起来。

照猫画虎,将这段文本复制过去即可。若文件和类名有什么其他命名规则,只需要更新这个宏就可以了,例如本文示例的 ViewController 类后面都有 VC,而 XIB 没有,所以此处的宏需要跟上VC才能跟VC的类关联起来:___FILEBASENAMEASIDENTIFIER___VC

如何关联配置中的自定义名称?

由系统模板的基类绑定可知,通过宏可以拿到配置文件中的值。添加一个 IdentifiertestStringtext 类型 option

自定义模板双输入框

我们在模板文件中加入这个宏进行测试:

//  配置文件中的testString为:(___VARIABLE_testString___)

创建模块后相关宏将被输入值所替换:

宏关联字段.png

还有哪些宏?

更多宏可查看官方文档在此

需要注意的是:
宏的前后各有三个下划线
宏的前后各有三个下划线
宏的前后各有三个下划线

如何将模块包含在文件夹中一并创建?

可以是可以···但目前创建出来的是文件(蓝色),而不是 Xcode 的 group文件(黄色),多方查阅资料后,项目模板是可以的,但文件模板不行(202007)。目前只能手动创建 group文件(黄色)。

如何让模块骚气一点(图标)?

模板可以自定义图标,系统模板提供了一倍图和二倍图,名称为 TemplateIcon,自定义图标只需在自定义模块文件下添加相同名称图片就可以了,效果如下:

黄暴的模板.png

Tips:
系统图标的大小为48x48(二倍图为96x96),大小不同也可以。

总结

Xcode 模板借助配置文件与宏对模板文件进行定制
不同的项目,规范不同,模板也就会有差异,开发者需根据项目具体规范,制定合适的模板才能事半功倍。

感谢阅读

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342