Xcode Source Editor Extension

2016-10-25  本文已影响212人  生光

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

不过既然提供了一种新技术,想必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是当前选中区域。然后就没了...
所以整个流程很简单:

在本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

上一篇下一篇

猜你喜欢

热点阅读