在平時(shí)開(kāi)發(fā)過(guò)程中我們使用了很多的Xcode插件酗洒,雖然官方對(duì)于插件制作沒(méi)有提供任何支持窗骑,但是加載三方的插件,默認(rèn)還是被允許的耳鸯。第三方的插件湿蛔,存放在
~/Library/Application Support/Developer/Shared/Xcode/Plug-ins文件夾中,后綴名必須是.xcplugin 县爬,其實(shí)際上是一種bundle阳啥。所以我們創(chuàng)建一個(gè)插件工程,直接創(chuàng)建bundle工程即可财喳。然后通過(guò)修改后綴名為.xcplugin察迟,將其放到~/Library/Application Support/Developer/Shared/Xcode/Plug-ins目錄中即可。
Xcode插件開(kāi)發(fā)現(xiàn)在主要通過(guò)兩種方式實(shí)現(xiàn)耳高,其實(shí)也就是一種扎瓶,只不過(guò)其中一種是使用別人提供的開(kāi)發(fā)模板來(lái)省去很多中間步驟而已。文章會(huì)依次詳細(xì)介紹兩種的實(shí)現(xiàn)方法泌枪。
準(zhǔn)備工作
方式一:通過(guò)Bundle實(shí)現(xiàn)
2.工程設(shè)置
插件工程和普通的bundle工程還是有區(qū)別的,所以需要進(jìn)行特殊的設(shè)置概荷。
1)工程的plist文件
添加三項(xiàng):
XCPluginHasUI = NO
XC4Compatible = YES
DVTPlugInCompatibilityUUIDs 這是一個(gè)數(shù)組。數(shù)組內(nèi)容字符串碌燕,指示了該插件兼容的Xcode版本误证,只有對(duì)應(yīng)版本的Xcode的UIID加入這個(gè)數(shù)組,插件才能被加載陆蟆。
否則雷厂,即使將插件放入Xcode的插件文件夾,插件也不會(huì)被加載叠殷。獲取當(dāng)前版本的Xcode的UUID方式:
在terminal中輸入命令:
defaults read /Applications/Xcode.app/Contents/Info DVTPlugInCompatibilityUUID
terminal會(huì)返回一串字符串改鲫,這就是Xcode的DVTPlugInCompatibilityUUID。
2)Build Setting
Installation Build Products Location 設(shè)置為 ${HOME} [顯示的時(shí)候,顯示的是你的用戶目錄](méi),這個(gè)是products的根目錄像棘。
Installation Directory 設(shè)置為 /Library/Application Support/Developer/Shared/Xcode/Plug-ins稽亏,這個(gè)是指定你的插件安裝的目錄。
注意缕题,這里填入的其實(shí)是相對(duì)目錄截歉。
插件的絕對(duì)目錄是這樣的,例如 /Users/yohunl/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/Alcatraz.xcplugin 烟零,最后的絕對(duì)目錄是 Installation Build Products Location和Installation Directory的結(jié)合瘪松,這也是為什么兩者都要設(shè)置的原因。
Deployment Location 設(shè)置為 YES锨阿,這個(gè)是指示該工程不使用設(shè)置里的build location宵睦,而是用Installation Directory來(lái)確定build后放置的位置。
默認(rèn)工程生成的相關(guān)文件位置都是 Build Locations指定的墅诡,通過(guò)Deployment Location 設(shè)置為 YES告訴工程壳嚎,我們不使用這個(gè)默認(rèn)的設(shè)置,而是我們自定義的末早。
Wrapper extension 設(shè)置為 xcplugin烟馅,后綴名必須為xcplugin,否則不會(huì)被加載然磷。
方式二:通過(guò)模板實(shí)現(xiàn)
1)下載Xcode插件開(kāi)發(fā)模板
地址:https://github.com/kattrali/Xcode-Plugin-Template
2)將下載下來(lái)的template復(fù)制到 ~/Library/Developer/Xcode/Templates/Project Templates/Application Plug-in/Xcode Plugin.xctemplate文件夾中郑趁,如果沒(méi)有對(duì)應(yīng)的文件夾就自己手動(dòng)創(chuàng)建一個(gè)。
3)重啟Xcode样屠,當(dāng)你新建一個(gè)工程的時(shí)候就可以在OS X中看到一個(gè)Application Plug-in的選項(xiàng)穿撮,里面有一個(gè)Xcode Plug-in模板。
實(shí)現(xiàn)
通過(guò)以上的兩種準(zhǔn)備方式痪欲,我們已可以創(chuàng)建Xcode插件工程悦穿,接下來(lái)就是如何實(shí)現(xiàn)插件功能。
1.功能需求
在當(dāng)前選中文件中實(shí)現(xiàn)代碼風(fēng)格重構(gòu)业踢,目前主要實(shí)現(xiàn)setter方法這一風(fēng)格重構(gòu)栗柒。例如,
[self setName:@"Davy"];
==> self.name = @"Davy";
2.思路分析
1)找到當(dāng)前文件中符合setter方法命名風(fēng)格的方法調(diào)用知举。
2)替換找到的符合重構(gòu)風(fēng)格的代碼瞬沦,提醒用戶保存。
3.技術(shù)難點(diǎn)
1)Xcode代碼編輯框文件內(nèi)容操作雇锡。
2)正則表達(dá)式書(shū)寫(xiě)逛钻。
3)Xcode代碼編輯框提醒用戶保存文件。
關(guān)于最后一點(diǎn)锰提,因?yàn)閄code對(duì)于沒(méi)有保存的已修改過(guò)的文件會(huì)顯灰以提示用戶該文件需要保存曙痘,我們可以借鑒這種方式芳悲。另外,在查找時(shí)边坤,如果能夠?qū)崿F(xiàn)高亮并且跟隨滾動(dòng)名扛,效果會(huì)更佳。
4.關(guān)鍵代碼
以上這些問(wèn)題茧痒,本人在“Refactor Code”插件中全部實(shí)現(xiàn)肮韧,現(xiàn)在放上關(guān)鍵方法。
1)添加菜單
-(void) setupMenuItem {
// Menu Item:
NSMenuItem *editMenuItem = [[NSApp mainMenu] itemWithTitle:@"Edit"];
if (editMenuItem) {
[[editMenuItem submenu] addItem:[NSMenuItem separatorItem]];
NSMenu *refactorCodeMenu = [[NSMenu alloc] initWithTitle:@"Refactor Code"];
NSMenuItem *menuItem;
menuItem = [[NSMenuItem alloc] initWithTitle:@"Refactor Method Style" action:@selector(refactorMethodStyleMenuAction) keyEquivalent:@""];
[menuItem setTarget:self]; [refactorCodeMenu addItem:menuItem];
NSMenuItem *refactorCodeMenuItem = [[NSMenuItem alloc] initWithTitle:@"Refactor Code" action:nil keyEquivalent:@""];
[refactorCodeMenuItem setSubmenu:refactorCodeMenu];
[[editMenuItem submenu] addItem:refactorCodeMenuItem];
}
}
2)顯示操作面板
- (void)refactorMethodStyleMenuAction {
[self.operateController showWindow:nil];
NSURL *url = [[NSBundle bundleForClass:[self class]] URLForResource:@"DZOperateController" withExtension:@"nib"];
if (!url) {
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = @"Refactor Method Style could not be shown because the plugin is corrupted.";
alert.informativeText = @"If you build the plugin from sources using Xcode, make sure to perform “Clean Build Folder“ in Xcode and then build the plugin again.\n\nIf you installed the plugin via Alctraz, there is a pending issue causing some files to be missing in the plugin. Prefer to install it via the plugin webpage.";
[alert addButtonWithTitle:@"Download Latest"];
[alert addButtonWithTitle:@"Cancel"];
NSModalResponse result = [alert runModal];
if (result == NSAlertFirstButtonReturn) {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://github.com/CharsDavy/RefactorCodePlugin-Xcode"]];
}
}
}
3)查找替換代碼風(fēng)格
這一部分是重點(diǎn)部分旺订,包括如何書(shū)寫(xiě)正則表達(dá)式弄企,并且利用正則表達(dá)式生成替換字符。還包括高亮代碼耸峭,具體可以參見(jiàn)本人源碼:https://github.com/CharsDavy/RefactorCodePlugin-Xcode
4)最終效果圖
提交插件至Alcatraz
1.打開(kāi)Alcatraz的插件包倉(cāng)庫(kù)桩蓉,地址:https://github.com/supermarin/alcatraz-packages
2.在簡(jiǎn)介里可以看到Alcatraz的包分為三類,分別為:插件(plugins)劳闹,配色方案(color schemes)和模板(templates)。每個(gè)包都必須包含”name”洽瞬、”url”和”description”字段本涕,還有一個(gè)可選的”screenshot”字段。
3.Fork這個(gè)倉(cāng)庫(kù)伙窃,再克隆到本地菩颖。
4.以添加”Refactor Code”插件為例,打開(kāi)packages.json文件为障,在”plugins”數(shù)組里加入:
{
"name": "Refactor Code",
"url": "https://github.com/CharsDavy/RefactorCodePlugin-Xcode.git",
"description": "Refactor code style,such as setter method.",
"screenshot": "https://github.com/CharsDavy/RefactorCodePlugin-Xcode/raw/master/Screenshots/window.png"
}
5.提交代碼到Fork的地址晦闰,再提交一個(gè)pull request到Master即可。
6.merged成功之后鳍怨,即可看見(jiàn)以下效果圖
希望對(duì)大家有所幫助呻右。