神刀安全网

Xcode Source Editor Extension

在 Xcode 8.0 的 beta 里面,Apple 引入了一个新的面向 macOS 的 App Extension,叫做 Xcode Source Editor Extension (以下简称插件),今天看到一个提问说是这个怎么弄,我简单看了一下 WWDC 的 Session: https:// developer.apple.com/vid eos/play/wwdc2016/414/ 现在总结在这里。首先我要说一下结论: 我对这个所谓的官方 Xcode 插件开发接口,非常的失望

其实官方还是宣扬了一些优点的,其中最显著的莫过于 可以上架 Mac App Store ,但这点优点实在是无法弥补他的弱鸡。他能做的事情几句话就可以说完,开发一个这样的插件是极其的简单。简单说吧,一个插件能做下面的事情:

  1. 获取 Xcode 正在编辑的文本

  2. 获取所有的选中区域

  3. 替换 Xcode 正在编辑的文本

  4. 选中 Xcode 正在编辑的文本

  5. 在 Xcode 的 Editor 菜单里面给你的插件生成一个子菜单,用于调用插件

  6. 可以在 Xcode 的 Key Binding 里面给插件分配一个快捷键

没了,这就是他全部能做的事情,下面我通过一个选中文字转换成 Base64 编码的例子来简单介绍一下。

Xcode Source Editor Extension

你需要在一个现有的或者新建的 macOS 项目里面新建一个 Xcode Source Editor Extension target,然后理论上这个时候已经可以有插件的效果了,但是今天我试了很多次就是不行,其实没有什么特别的原因,就是因为 Xcode 目前的阶段极其不稳定,我没写错任何东西。

有几个核心的观念要介绍一下,首先,实现了 XCSourceEditorExtension 接口的类,用于管理插件的生命周期或者对 Command 进行动态配置,说的很牛逼其实一共两个方法。

- (void)extensionDidFinishLaunching {     // If your extension needs to do any work at launch, implement this optional method. }  - (NSArray <NSDictionary <XCSourceEditorCommandDefinitionKey, id> *> *)commandDefinitions {     // If your extension needs to return a collection of command definitions that differs from those in its Info.plist, implement this optional property getter.     return @[]; } 

分别是在插件成功加载后调用和动态配置 Command,但是 Command 也可以静态的配置在插件的 Plist 上面,我的例子里面其实就是这么一个结构:

<dict>     <key>XCSourceEditorCommandDefinitions</key>     <array>         <dict>             <key>XCSourceEditorCommandClassName</key>             <string>SourceEditorCommand</string>             <key>XCSourceEditorCommandIdentifier</key>             <string>app.cyan.XcodeExtension.xEncoders.SourceEditorCommand</string>             <key>XCSourceEditorCommandName</key>             <string>Base64 Encode</string>         </dict>     </array>     <key>XCSourceEditorExtensionPrincipalClass</key>     <string>SourceEditorExtension</string> </dict> 

没什么好解释的,指定了实现类的名称和菜单的名称。

XCSourceEditorCommand 是另外一个核心概念,其实就是当插件被触发之后,你有机会在代理方法里面拦截到这个消息(XCSourceEditorCommandInvocation),做出处理之后将内容返回给 Xcode,仅此而已。

XCSourceEditorCommandInvocation 里面会存放一些 meta 数据,其中最重要的是 identifier 和 buffer,identifier 就是用来做区分的,buffer 则是整个插件中最最重要的概念,但是他其实也很简单。

XCSourceTextBuffer 最重要的环节有两个,

/** 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; 

分别表示了 传递过来的文本,以及选中区域 。所以要做的事情已经一目了然了,流程如下:

  1. 在菜单或快捷键触发插件

  2. XCSourceEditorCommand 拦截了消息

  3. 从 invocation 中拿到 buffer

  4. 在 buffer 中根据当前行,获取到你要的数据

  5. 把数据替换后塞回去

所以这个 Base64 的例子,最后就只有这么几行代码(只处理一行文本的情况下)

static inline NSString *Base64Encode(NSString *string) {     NSData *encodedData = [string dataUsingEncoding:NSUTF8StringEncoding];     return [encodedData base64EncodedStringWithOptions:0]; }  - (void)performCommandWithInvocation:(XCSourceEditorCommandInvocation *)invocation completionHandler:(void (^)(NSError * _Nullable nilOrError))completionHandler {          XCSourceTextRange *selection = invocation.buffer.selections.firstObject;     NSInteger index = selection.start.line;     NSString *text = invocation.buffer.lines[index];     invocation.buffer.lines[index] = Base64Encode(text);      completionHandler(nil); } 

最后把插件编译运行到 Xcode 8 beta 上面,会出现一个被调试的 Xcode,是黑色的: Xcode Source Editor Extension

然后随便选个项目跑起来,菜单里面就有了插件了

Xcode Source Editor Extension

我说的轻巧,其实现实中(目前 beta1),出现菜单的概率非常的低,这让我非常恼火。

当然这个插件开发模式的确能拿来做一些事情,比如代码的格式化,或者是编解码,总之都集中在 文本的处理体验上面 。但他的局限性也是非常的明显,例如:

  • 没有 UI 相关的接口,纯粹只能做文本处理

  • 没办法直接绑定快捷键,还得到 Xcode 的设置里面去设置

  • 就目前而言,调试的成功率实在是太低了,很郁闷
  • 只能通过菜单或快捷键调用
  • 只能处理编辑区域

这些和第三方的 Xcode 插件比起来要差的很远,不过这还算是一个不错的开端,希望在日后可以把更多的接口开放出来,让 Xcode 这个本来就让人恼火的东西变得更好用。

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Xcode Source Editor Extension

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址