很多时候我们需要一个较复杂场景的Demo工程来验证点东西或者研究某个技术,直接在公司项目工程中实验运行又太慢,并且还可能受到其他代码的影响。而Xcode自身提供的工程模板又太过简单,导致每次都要浪费很多时间编写重复的代码来搭建环境。为了提高效率,我们可以自定义工程模板和文件模板。
如下图,系统提供的默认模板其实都在Xcode.app
中,自定义工程模板和文件模板最好的办法就是参考系统的模板。
系统的工程模板位置:
1 | /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/Project Templates/iOS |
系统的文件模板位置:
1 | /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File Templates |
以上是系统默认的模板存储路径,对于自定义的模板则需要存放在其他路径:
自定义工程模板的路径需要存放在:~/Library/Developer/Xcode/Templates/Project Templates/Application/
.
自定义文件模板的路径需要存放在:~/Library/Developer/Xcode/Templates/File Templates/
.
当做好自己的模板后只需要存放在上述位置,重启Xcode就能看到我们自己的工程模板了。
注:如果上述路径不存在则需要自己创建好。
了解系统的工程模板
在制作自己的工程模板之前,先来了解一下系统的工程模板都有些啥,以最简单的Single View App模板为例:
每个模板文件夹中都会包含一个模板信息的plist文件里面是一些关于模板的配置。我们要做的也就是修改TemplateInfo.plist文件。
简单介绍一下TemplateInfo.plist文件:
Kind
分为工程模板和文件模板,这个不用修改使用默认的就好。
工程模板:Xcode.Xcode3.ProjectTemplateUnitKind
文件模板:Xcode.IDEFoundation.TextSubstitutionFileTemplateKind
Identifier
模板ID,用于唯一标识一个模板。类似于类名。
Ancestors
模板系统允许模板继承和重写其他模板,Ancestors里面包含的就是当前模板继承的其他模板的ID(就是上面那个Identifier)。
Single View App模板的Ancestors包含两个父模板:
com.apple.dt.unit.coreDataCocoaTouchApplication
:如果你在创建工程时勾线了CoreData,这个模板就会让Xcode在AppDelegate中添加CoreData的样板文件。
com.apple.dt.unit.sceneLifecycleApplication
:这个是iOS13出的,会让Xcode创建SceneDelegate.h/m。
上面两个模板又都继承自Cocoa Touch Application Base模板,
com.apple.dt.unit.cocoaTouchApplicationBase
:这个模板主要是在AppDelegate中添加一些样板代码和Info.plist的一些设置。
允许模板的继承和重写就可以让各个模板功能清晰,代码复用,达到类似于类的继承的效果。
Concrete
必须设置为YES才能在Xcode面板中显示出来。
Description
模板的描述。
SortOrder
模板在Xcode面板中的显示位置。值越大显示在越后面。
Options
这个就是模板的主要内容了,里面包括要创建的类文件,存根方法的实现等。Nodes里定义了一些key,它的值就是Definitions里的东西。参照系统的写法我们就可以依葫芦画瓢制作自己的模板了。
制作自己的工程模板
接下来制作自己的工程模板,使用该模板创建的Demo工程将自动包含一个tabBar控制器,及三个子navigation控制器。其中的MATHomeViewController上添加了一个tableView,MATMessageViewController上添加了一个按钮。支持OC和Swift。
首先拷贝一份系统的Single View App模板,我们主要基于Single View App模板进行修改。
修改文件名为Demo App.xctemplate
,文件夹下的模板图标可以换一下。接下来就是对TemplateInfo.plist文件的修改了。
Identifier
随便取个名称,com.apple.dt.unit.MATDemoApplication
。
Ancestors
由于不想要Storyboard,所以用com.apple.dt.unit.cocoaTouchApplicationBase
替换掉com.apple.dt.unit.sceneLifecycleApplication
模板。
SortOrder
取值100。让它排在系统的后面。
接下来就是大头Options。
Options
更改AppDelegate
在Nodes里添加一个item AppDelegate.m:imports:importHeader:MATTabBarController.h
:表示在AppDelegate.m里面导入MATTabBarController.h头文件,这样Xcode在创建工程时就会自动在AppDelegate.m里添加#import"MATTabBarController.h"
。
在Nodes里添加一个item AppDelegate.m:implementation:methods:applicationdidFinishLaunchingWithOptions:body
并在Definitions里添加对应的值:
1 | self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; |
这样Xcode就会自动在AppDelegate.m里didFinishLaunchingWithOptions方法里面添加上述代码。
如图:
Nodes:
Definitions:
添加已有的类文件
MATTabBarController.h/m是我们自己提供的类文件,为了让Xcode在创建工程时能够找到这些类,我们需要在模板文件中指明。
在Nodes里添加两个item:MATTabBarController.h
和MATTabBarController.m
并在Definitions里添加对应的值:
key:MATTabBarController.h
,value类型选择字典。字典中添加key:Path
,value为文件的路径。
动态创建类
这个参照系统的就可以了:
红色划线处替换为你自己的类名即可。
添加方法
让Xcode在创建的类中自动添加一个方法。
在Nodes里添加两个item:
MATMessageViewController.m:implementation:methods:btnDidClicked(- (void\)btnDidClicked:(UIButton *\)sender)
和
MATMessageViewController.m:implementation:methods:btnDidClicked:body
即方法声明和方法实现。
在Definitions里添加MATMessageViewController.m:implementation:methods:btnDidClicked:body
的值,这里就是btnDidClicked方法的实现:
1 | NSLog(@"btnDidClicked"); |
添加属性及懒加载实现
让Xcode在创建的类中自动添加一个属性及属性的懒加载实现。
在Nodes里添加三个item
MATMessageViewController.m:extension:btn
MATMessageViewController.m:implementation:methods:btn(- (UIButton *\)btn)
MATMessageViewController.m:implementation:methods:btn:return
在Definitions添加对应的值:
MATMessageViewController.m:extension:btn
的值:
@property (strong, nonatomic) UIButton *btn;
MATMessageViewController.m:implementation:methods:btn:return
的值:
1 | if (_btn == nil) { |
到此为止工程模板就差不多了,将其拷贝到~/Library/Developer/Xcode/Templates/Project Templates/Application/
目录下,重启Xcode就可以看到我们自己的模板了。
制作自己的文件模板
制作文件模板最好也是参照系统的文件模板。
新建一个文件夹命名为ZACustom
,然后从目录:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File Templates/Source
拷贝一份Cocoa Touch Class.xctemplate
,到该目录下。
一般新建UIViewController和NSObject较多,所以可以只保留这两个类,其他的类文件夹可以删掉。
文件模板的TemplateInfo.plist文件基本不需要修改,只需要修改各类文件夹下的___FILEBASENAME___.m
文件。
修改UIViewControllerObjective-C
文件夹下的___FILEBASENAME___.m
,新增代码如下:
1 | //___FILEHEADER___ |
这样创建的UIViewController子类就自带这些注释和实现的方法。
可以修改NSObjectObjective-C
文件夹下的___FILEBASENAME___.h
,如下:
1 | //___FILEHEADER___ |
这样创建的模型,自动就有7个占位属性了。
最后将文件夹ZACustom
拷贝到~/Library/Developer/Xcode/Templates/File Templates/
目录下,重启Xcode就可以看到我们自己定义的文件模板了。
有需要的朋友可以点击下方链接下载使用: