Xcode插件開(kāi)發(fā)教程指南

在平時(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)

1.創(chuàng)建Bundle工程


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ì)大家有所幫助呻右。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鞋喇,隨后出現(xiàn)的幾起案子声滥,更是在濱河造成了極大的恐慌,老刑警劉巖侦香,帶你破解...
    沈念sama閱讀 223,002評(píng)論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件落塑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡罐韩,警方通過(guò)查閱死者的電腦和手機(jī)憾赁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)散吵,“玉大人龙考,你說(shuō)我怎么就攤上這事蟆肆。” “怎么了洲愤?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,787評(píng)論 0 365
  • 文/不壞的土叔 我叫張陵颓芭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我柬赐,道長(zhǎng)亡问,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,237評(píng)論 1 300
  • 正文 為了忘掉前任肛宋,我火速辦了婚禮州藕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘酝陈。我一直安慰自己床玻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,237評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布沉帮。 她就那樣靜靜地躺著锈死,像睡著了一般。 火紅的嫁衣襯著肌膚如雪穆壕。 梳的紋絲不亂的頭發(fā)上待牵,一...
    開(kāi)封第一講書(shū)人閱讀 52,821評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音喇勋,去河邊找鬼缨该。 笑死,一個(gè)胖子當(dāng)著我的面吹牛川背,可吹牛的內(nèi)容都是我干的贰拿。 我是一名探鬼主播,決...
    沈念sama閱讀 41,236評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼熄云,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼膨更!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起皱碘,我...
    開(kāi)封第一講書(shū)人閱讀 40,196評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤询一,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后癌椿,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體健蕊,經(jīng)...
    沈念sama閱讀 46,716評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,794評(píng)論 3 343
  • 正文 我和宋清朗相戀三年踢俄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缩功。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,928評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡都办,死狀恐怖嫡锌,靈堂內(nèi)的尸體忽然破棺而出虑稼,到底是詐尸還是另有隱情,我是刑警寧澤势木,帶...
    沈念sama閱讀 36,583評(píng)論 5 351
  • 正文 年R本政府宣布蛛倦,位于F島的核電站,受9級(jí)特大地震影響啦桌,放射性物質(zhì)發(fā)生泄漏溯壶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,264評(píng)論 3 336
  • 文/蒙蒙 一甫男、第九天 我趴在偏房一處隱蔽的房頂上張望且改。 院中可真熱鬧,春花似錦板驳、人聲如沸又跛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,755評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)慨蓝。三九已至,卻和暖如春端幼,著一層夾襖步出監(jiān)牢的瞬間菌仁,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,869評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工静暂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谱秽。 一個(gè)月前我還...
    沈念sama閱讀 49,378評(píng)論 3 379
  • 正文 我出身青樓洽蛀,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親疟赊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子郊供,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,937評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容