转自:http://joeyio.com/ios/2013/07/25/write_xcode4_plugin_of_your_own/ios
刚写iOS程序的时候就知道Xcode支持第三方插件,好比ColorSense等很实用的插件,但Xcode的插件开发没有官方的文档支持,一直以为很神秘,那今天就来揭开它的面纱。git
在Xcode启动的时候,它会检查插件目录(~/Library/Application Support/Developer/Shared/Xcode/Plug-ins
)下全部的插件(扩展名为.xcplugin
的bundle文件)并加载他们。其实到这里咱们就猜到了,咱们作的插件最终会是一个扩展名为.xcplugin
的bundle文件,放在插件目录下供Xcode加载。github
OK,咱们先作一个简单的插件,须要很简单的几个步骤便可完成,个人环境是Xcode 4.6.3 (4H1503)。xcode
Xcode插件其实就是一个Mac OS X bundle,因此能够参考下图建立一个Bundle。 app
给Project起个名字,并确保不要勾选Use automatic reference counting
,由于Xcode是使用GC来管理内存的,因此Xcode的插件也须要是用GC来管理内存的。Framework选择Cocoa
。编辑器
像下图同样设置这些信息ui
XC4Compatible
= YES
XCPluginHasUI
= NO
XCGCReady
= YES
Principal Class
= Plugin
(这个设置为你插件的名字
,本例中命名为Plugin
)前三个可能Info里缺省没有,能够本身添加,都选Boolean
类型,最后一个Principal Class
是String
类型。 spa
而后打开Build Setting Tab,设置这些:插件
Installation Build Products Location
为${HOME}
,Xcode会自动转换为你当前用户的Home路径Installation Directory
为/Library/Application Support/Developer/Shared/Xcode/Plug-ins
, Xcode会把拼接Installation Build Products Location
和Installation Directory
为一个绝对路径来查找你的插件Deployment Location
为 YES
Set Wrapper extension
为 xcplugin
##4. 添加 User-Defined 设置调试
GCC_ENABLE_OBJC_GC
为 supported
GCC_MODEL_TUNING
为 G5
有了这些设置,每次build这个Projct的时候,Xcode就会把build后的插件copy到plugin文件夹下,而后咱们须要重启Xcode来从新加载新build的插件。开发插件相对来讲简单一些,调试插件就比较纠结了,惟一的办法就是build以后,重启Xcode,来加载最新build的插件。
准备工做已经结束,下面开始实现咱们的插件。
在第二步的时候咱们设置了一个Principal Class
,那么在Xcode里新建Objective-C类,名字和Principal Class
设置的值保持一致。在实现文件中添加上+ (void) pluginDidLoad: (NSBundle*) plugin
方法。 该方法会在Xcode加载插件的时候被调用,能够用来作一些初始化的操做。一般这个类是一个单例,并Observe了NSApplicationDidFinishLaunchingNotification
,用来得到Xcode加载完毕的通知。
+ (void) pluginDidLoad: (NSBundle*) plugin { static id sharedPlugin = nil; static dispatch_once_t once; dispatch_once(&once, ^{ sharedPlugin = [[self alloc] init]; }); } - (id)init { if (self = [super init]) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidFinishLaunching:) name:NSApplicationDidFinishLaunchingNotification object:nil]; } return self; }
一旦接收到Xcode加载完毕的通知,就能够Observe须要的其余notification或者在菜单中添加菜单项或者访问Code Editor之类的UI组件。
在咱们的这个简单例子中,咱们就在Edit
下添加一个叫作Custom Plugin
的菜单项,并设置一个⌥ + c
快捷键。它的功能是使用NSAlert
显示出咱们在代码编辑器中选中的文本。咱们须要经过观察NSTextViewDidChangeSelectionNotification
并访问接收参数中的NSTextView
,来得到被选中的文本。
- (void) applicationDidFinishLaunching: (NSNotification*) notification { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(selectionDidChange:) name:NSTextViewDidChangeSelectionNotification object:nil]; NSMenuItem* editMenuItem = [[NSApp mainMenu] itemWithTitle:@"Edit"]; if (editMenuItem) { [[editMenuItem submenu] addItem:[NSMenuItem separatorItem]]; NSMenuItem* newMenuItem = [[NSMenuItem alloc] initWithTitle:@"Custom Plugin" action:@selector(showMessageBox:) keyEquivalent:@"c"]; [newMenuItem setTarget:self]; [newMenuItem setKeyEquivalentModifierMask: NSAlternateKeyMask]; [[editMenuItem submenu] addItem:newMenuItem]; [newMenuItem release]; } } - (void) selectionDidChange: (NSNotification*) notification { if ([[notification object] isKindOfClass:[NSTextView class]]) { NSTextView* textView = (NSTextView *)[notification object]; NSArray* selectedRanges = [textView selectedRanges]; if (selectedRanges.count==0) { return; } NSRange selectedRange = [[selectedRanges objectAtIndex:0] rangeValue]; NSString* text = textView.textStorage.string; selectedText = [text substringWithRange:selectedRange]; } } - (void) showMessageBox: (id) origin { NSAlert *alert = [[[NSAlert alloc] init] autorelease]; [alert setMessageText: selectedText]; [alert runModal]; }
你会发如今出现selectedText的地方会报错,在实现里添加上NSString *selectedText
便可。
@implementation Plugin { NSString *selectedText; }
最终效果:
tail -f /var/log/system.log
命令来查看输出的日志~/Library/Application Support/Developer/Shared/Xcode/Plug-ins
目录下,把插件删掉,restart Xcode,查找问题在哪这只是一个简单的Xcode插件的入门编写示例,不过“麻雀虽小,五脏俱全”,能够了解到Xcode的插件一些东西,好比Xcode插件本质上其实就是一个Mac OS X bundle等等,并且由于没有Apple官方的文档的支持,不少东西只能去Google,或者参考别人插件的一些实现。
本文主要参考和编译自WRITING YOUR OWN XCODE 4 PLUGINS,感谢原做者Blacksmith Software
另: 前两天咱们的小伙伴@onevcat写了一个Xcode插件VVDocumenter,做用是在方法、类等前面输入三个/就会自动生成规范的JavaDoc文档(Xcode5中将支持JavaDoc类型的文档,对于我这样从Java转过来的来讲是真是雪中送炭),赶忙clone了一个,用起来很方便,很好很强大,强烈推荐! 赶忙把咱们的项目代码文档化起来,迎接Xcode5的到来吧,:)
Enjoy!!!