美文网首页
Xcode Source Editor Extension

Xcode Source Editor Extension

作者: 生光 | 来源:发表于2016-10-25 11:46 被阅读212次

    不知道是不是受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

    相关文章

      网友评论

          本文标题:Xcode Source Editor Extension

          本文链接:https://www.haomeiwen.com/subject/birruttx.html