Xcode Source Editor Extension

不知道是不是受xcodeghost的影响,现在任何library和bundle都需要Xcode8认证许可,通过注入code实现第三方功能的plugin也不允许在Xcode8上使用。取而代之的,Apple提供了一种新技术,通过为Xcode开发扩展,获取并改变开发环境,从而实现类似plugin的功能。这个技术就是Xcode Source Editor Extension(以下简称xsee)。
要指出的是,xsee虽然打开了一条新道路,但作为新技术,目前仍然是不成熟并且功能也很有限。

  • xsee只能获取和修改source code,并不能像很多功能强大的插件,对整个工程作出修改。
  • 本质是extension,必须依存于MacOS app
  • 没有自己单独的UI interface
  • 只能通过Xcode command方式触发

不过既然提供了一种新技术,想必Apple也会在这个方向上有所深入,未来应该会提供更多更全面的功能。

Demo: 类似VVDocumenter为方法添加注释

以下通过实现一个类似VVDocumenter的demo,来介绍如何创建使用xsee。

  1. 新建MacOS app
    xsee本质是mac extension,所以需要新建一个MacOS app。


    create MacOS app.png
  2. 创建extension
    file -> new -> target 创建Xcode Source Editor Extension


    create xsee.png
  3. 设置并运行
    编辑extension的scheme,设置executable为Xcode.app,即mac上安装的Xcode8。


    set extension.png

    运行extension,就会生成一个自定义Xcode环境,在菜单栏的Editor下,可以看到一个新的command,点击该command会触发扩展功能。


    customer xcode.png
  4. 分析code structure
    新建的extension结构很简单,默认创建几个文件:

Info.plist
SourceEditorCommand.h
SourceEditorCommand.m
SourceEditorExtension.h
SourceEditorExtension.m

SourceEditorExtension中定义了extension的life cycle,虽然只有一个launch 函数。command信息无需在commandDefinitions中设定,可以直接到info.plist中设置:

<key>NSExtension</key>
 <dict>
  <key>NSExtensionAttributes</key>
  <dict>
   <key>XCSourceEditorCommandDefinitions</key>
   <array>
    <dict>
     <key>XCSourceEditorCommandClassName</key>
     <string>SourceEditorCommand</string>
     <key>XCSourceEditorCommandIdentifier</key>
     <string>HAC.addDocuments</string>
     <key>XCSourceEditorCommandName</key>
     <string>Sakura</string>
    </dict>
   </array>
   <key>XCSourceEditorExtensionPrincipalClass</key>
   <string>SourceEditorExtension</string>
  </dict>
  <key>NSExtensionPointIdentifier</key>
  <string>com.apple.dt.Xcode.extension.source-editor</string>
 </dict>

SourceEditorCommand中定义了command触发的回调函数,具体的处理逻辑放在

- (void)performCommandWithInvocation:(XCSourceEditorCommandInvocation *)invocation completionHandler:(void (^)(NSError * _Nullable nilOrError))completionHandler
{
  // Implement your command here, invoking the completion handler when done. Pass it nil on success, and an NSError on failure.
  [HACExtensionManager handleInvocation:invocation];
  completionHandler(nil);
}

方法传入的参数XCSourceEditorCommandInvocation即保存着当前source code的所有信息,最重要的是identifier和buffer,前者即定义在info.plist中的command id,做区分;buffer即缓存的环境信息,不过目前信息很少,重要的一个是lines一个是section

/** The lines of text in the buffer, including line endings. Line breaks within a single buffer are expected to be consistent. Adding a "line" that itself contains line breaks will actually modify the array as well, changing its count, such that each line added is a separate element. */
@property (readonly, strong) NSMutableArray <NSString *> *lines;

/** The text selections in the buffer; an empty range represents an insertion point. Modifying the lines of text in the buffer will automatically update the selections to match. */
@property (readonly, strong) NSMutableArray <XCSourceTextRange *> *selections;

lines是source code的行信息,selection是当前选中区域。然后就没了...
所以整个流程很简单:

  • 启动extension,回调extensionDidFinishLaunching
  • 菜单或快捷键触发command
  • 拦截command,调用performCommandWithInvocation
  • 获取当前环境信息XCSourceEditorCommandInvocation,处理并回塞数据到buffer
  • 刷新Xcode环境

在本demo中,逻辑很简单:

  • 取得当前选中区后面的文本
  • 遍历匹配最接近的一个方法
  • 正则表达式解析出方法名,返回类型,参数
  • 生成注释信息
  • 将注释信息回塞到选中区后一行。

tips

如果在OS 10.11上运行,可能需要运行命令:

sudo /usr/libexec/xpccachectl 

并且在 Xcode 尝试加载扩展之前重启。这是因为安装新的 SDK 以及 El Capitan 的 XPC 服务不允许这样的操作。
参考资料时,很多人反映extension性能还很不稳定。目前在Xcode8正式版本上,感觉还是很可靠的,当然目前只是初步体验,demo很简单。

参考链接:
How to Create an Xcode Source Editor Extension

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容