Xcode 自动生成代码插件开发

Xcode8 开放了新的一个Extension:Xcode Source Editor Extension,可以让我们自己开发Xcode 插件,但是目前开发的API 还比较少,但是也不妨碍我们了解和使用。本文主要介绍如何使用Xcode Source Editor Extension 实现一个简单的自动生成代码的插件。

地址GitHub

效果

Xcode 自动生成代码插件开发_第1张图片
Untitled.gif

实现

新建一个MacOS 宿主项目,再新建一个Target,类型为Xcode Source Editor Extension,并且设置target的签名和宿主App的签名一致。

Xcode 自动生成代码插件开发_第2张图片
屏幕快照 2018-01-24 下午7.53.25.png
Xcode 自动生成代码插件开发_第3张图片
屏幕快照 2018-01-24 下午7.53.50.png

目录结构

Xcode 自动生成代码插件开发_第4张图片
屏幕快照 2018-01-24 下午7.54.37.png

系统默认为我们生成SourceEditorCommand 文件,其中这个方法就当做主入口,当调用插件时会执行这个方法。但是只能获取到当前编辑文件的内容,不能获取整个工程。

    func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void ) -> Void {
        // Implement your command here, invoking the completion handler when done. Pass it nil on success, and an NSError on failure.
        
        if invocation.commandIdentifier == InsetCodeKey {
            handleInsertCode(invocation: invocation)
        }else{
            NSWorkspace.shared.open(URL.init(fileURLWithPath: "/Applications/GenerateCode.app"))
        }
        completionHandler(nil)
    }

核心代码如下,大致逻辑是获取当前输入的key,根据提前录入的Map,查找对应Value,并且替换当前行内容。

func handleInsertCode(invocation: XCSourceEditorCommandInvocation){
        let selection = invocation.buffer.selections.firstObject as! XCSourceTextRange
        let totalLines = invocation.buffer.lines
        let curIndex = selection.start.line
        var curLineContent = totalLines[curIndex] as! String
        
        let mapKey = curLineContent.trimmingCharacters(in: .whitespacesAndNewlines)
        
        let map = SharedUserDefault.shared.mapping
        if let value = map[mapKey] {
            let arr = convertToLines(string: value)
            var numberOfSpaceIndent = curLineContent.range(of: mapKey)!.lowerBound.encodedOffset
            var indentStr = ""
            
            while numberOfSpaceIndent > 0 {
                indentStr = indentStr.appending(" ")
                numberOfSpaceIndent -= 1
            }
            if arr.isEmpty{
                return
            }
            if let range = curLineContent.range(of: mapKey){
                curLineContent.replaceSubrange(range, with: arr[0])
                totalLines[curIndex] = curLineContent
            }
            for i in 1..

录入界面

Xcode 自动生成代码插件开发_第5张图片
屏幕快照 2018-01-24 下午7.59.38.png

在主工程中,创建录入界面,整体是个NSTableView,展示保存好的Map,双击某一行或者点击添加按钮,进入编辑页面,主要用NSTextField 实现

Xcode 自动生成代码插件开发_第6张图片
屏幕快照 2018-01-24 下午8.02.28.png

全局保存的Map 存储在UserDefaults 里,但是宿主和扩展共享数据的话,需要suiteName 相同才行,需要在App Group 里设置相同的key。

测试

  1. 先运行主App,测试添加数据是否正常

  2. 运行插件,选择Xcode,会出来一个灰色的Xcode,随便打开一个项目

Xcode 自动生成代码插件开发_第7张图片
屏幕快照 2018-01-24 下午8.07.17.png

输入key,运行插件,正确生成代码。

Xcode 自动生成代码插件开发_第8张图片
屏幕快照 2018-01-24 下午8.07.58.png

也可以绑定快键键

Xcode 自动生成代码插件开发_第9张图片
屏幕快照 2018-01-24 下午8.10.08.png

使用

Xcode 自动生成代码插件开发_第10张图片
屏幕快照 2018-01-24 下午8.10.56.png

将app 拷入应用程序里,并且将设置里Xcode 扩展选上,重启Xcode,就能在Editor 里使用啦

Xcode 自动生成代码插件开发_第11张图片
屏幕快照 2018-01-24 下午8.12.07.png

总结

插件主要参考了EasyCode,站在了巨人的肩膀上。但是目前EasyCode 好像Swift 不能用,因为媳妇开发用的纯Swift,所以主要写给她用的,目前插件的功能还很简单,但是基本可以使用了,后续可以继续优化!

参考

WWDC2016
Xcode Source Editor Extension

你可能感兴趣的:(Xcode 自动生成代码插件开发)