Xcode提供了所有你創建一個App需要的功能。但是由於其不開源以及沒有制作Xcode-Plugin相關的文檔,在我們需要添加一些自己的想法和功能的時候變得缺乏靈活性。 但是我們可以通過一些非官方的手段來擴展我們自己的Xcode,並且分享給別人使用。
Xcode Plug-in能做什麼
太多了,我們可以自動生成代碼注釋(VVDocumenter),我們可以在代碼編輯器中直接顯示我們初始化的UIColor的顏色(ColorSense-for-Xcode),我們也可以在代碼編輯器中直接顯示我們要添加到UIImage的圖片(KSImageNamed-Xcode),我們還可以調整控制台的顏色,修改代碼樣式,等等等等….
我們還可以用Alcatraz來管理我們的插件,簡直方便!
Xcode Plug-in放在哪
所有的Xcode Plug-in都會放在一個叫
~/Library/Application Support/Developer/Shared/Xcode/Plug-ins文件目錄下,並且所有的插件都會以.xcplugin作為後綴。
開發自己的Xcode Plug-in
准備工作
進入開發
我們新建一個Xcode Plug-in模板的工程,可以看到模板為我們生成了好多代碼。看與你工程同名的文件的initWithBundle方法。閱讀一下後你就可以知道模板為我們填充了一個在Edit中添加一個Do Action的按鈕,點擊後會回調doMenuAction方法。
我們可以run一下我們的工程,你會發現啟動了一個新的Xcode,因為我們做的是Xcode插件,啟動的當然是Xcode,用Xcode編寫Xcode的代碼,是不是很有意思。試試點擊新的Xcode的Edit有一個Do Action按鈕,點擊Do Action按鈕,再回調中打個斷點,看有沒有回調你的方法。
DVTPlugInCompatibilityUUIDs
是的,你會發現你的回調方法木有調用,木有調用啊,什麼鬼!其實這是因為你的插件不認識你正在跑的Xcode的版本,把你的Xcode版本介紹給它認識就好了。
竊聽Xcode通知
因為Apple至今也沒有公開Xcode Plugin的文檔。所以我們需要通過一些其他的思路尋找方法。比如竊聽我們在操作Xcode的時候Xcode發出的各種通知。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationLog:) name:nil object:nil];
將這行代碼加入到我們的工程初始化中
- (void)notificationLog:(NSNotification *)notify { NSLog(@"%@",notify.name); }
這樣我們就可以監聽我們在對xcode做操作的時候xcode發出的所有通知了。跑一下,是不是通知刷刷的來了。。。
實現一個Xcode插件功能
尋找需求
既然我們都知道了這麼多通知,我們是不是可以通過抓取其中某一個通知動手優化下Xcode呢。現在Xcode插件辣麼多,好多咱們能想到的功能,其實用心在網上google一下,都能找到。鑒於入門,那麼我們來坐一個比較簡單的功能吧。
比如我們在xcode文件導航區域要顯示這個文件在Finder中的位置的時候,我們需要在這個文件中右鍵點擊,然後在展示列表中點擊show in finder,而且這個show in finder按鈕還沒有快捷鍵。要是能有個快捷鍵能夠快速打開就好了。
構思實現
talk is cheep,show u the code
1.我們需要監聽文件導航區域選中的文件改變時候的通知,然後保存當前選中的文件的路徑
根據之前監聽xcode通知,我們會發現一個叫transition from one file to another這個通知,這就是我們需要的選中文件改變時候的通知。
- (void)notificationLog:(NSNotification *)notify { if ([notify.name isEqualToString:@"transition from one file to another"]) { NSURL *originURL = [[notify.object valueForKey:@"next"] valueForKey:@"documentURL"]; if (originURL != nil && [originURL absoluteString].length >= 7 ) { self.url = [originURL.absoluteString substringFromIndex:7]; } } }
我們將這個通知給我們的文件路徑保存下來,為什麼要substringFromIndex:7,因為返回的URL是file:///User........格式的,需要切換成/User...的格式。
2.我們需要新建一個NSMenuItem,然後設置我們需要的快捷鍵。
這個比較簡單修改下模板幫我們生成的那幾行代碼,加入快捷鍵就可以
NSMenuItem *menuItem = [[NSApp mainMenu] itemWithTitle:@"Edit"]; if (menuItem) { [[menuItem submenu] addItem:[NSMenuItem separatorItem]]; NSMenuItem *actionMenuItem = [[NSMenuItem alloc] initWithTitle:@"Do action" action:@selector(doMenuAction) keyEquivalent:@"F"]; [actionMenuItem setKeyEquivalentModifierMask:NSShiftKeyMask]; [actionMenuItem setTarget:self]; [[menuItem submenu] addItem:actionMenuItem]; }
objective-c
關鍵在於這兩行:
NSMenuItem *actionMenuItem = [[NSMenuItem alloc] initWithTitle:@"Do action" action:@selector(doMenuAction) keyEquivalent:@"F"]; [actionMenuItem setKey
這裡的快捷鍵就是shift + F,讀者可以根據自己的方式修改。
3.當我們按下快捷鍵的時候打開我們的workspace,並且選中到指定的文件。
- (void)doMenuAction { self.url = [self.url stringByURLDecodingStringParameter]; [[NSWorkspace sharedWorkspace] selectFile:self.url inFileViewerRootedAtPath:nil]; }
這個就比較好理解了。把第一步保存的URL傳遞過去就可以,不過需要做一個URLDecoding,因為xcode給我們的是encode過的URL。
Xcode “API”
Xcode插件開發已經不是什麼新技術了,所以也有很多開發者dump出了很多Xcode的API。大家可以按需要加入到自己的工程中使用。
Working with projects files
XcodeEditor有一組強大的操縱項目文件的API,比如inspect headers, list frameworks, add classes等功能。如果你要對你項目文件進行操作,千萬不要忘記這個庫。
NSTask
NSTask的功能類似像terminal中執行command命令一樣,非常實用。
nstask-tutorial
Cocoa
是Cocoa,不是Cocoa touch,應為Xcode是MacOS上的app。所以編寫Xcode插件會用到很多Cocoa的API,需要了解Cocoa編程。