Xcode 自動生成代碼插件開發(fā)

Xcode8 開放了新的一個Extension:Xcode Source Editor Extension,可以讓我們自己開發(fā)Xcode 插件,但是目前開發(fā)的API 還比較少,但是也不妨礙我們了解和使用。本文主要介紹如何使用Xcode Source Editor Extension 實現(xiàn)一個簡單的自動生成代碼的插件。

地址GitHub

效果

Untitled.gif

實現(xiàn)

新建一個MacOS 宿主項目,再新建一個Target,類型為Xcode Source Editor Extension,并且設(shè)置target的簽名和宿主App的簽名一致。

屏幕快照 2018-01-24 下午7.53.25.png
屏幕快照 2018-01-24 下午7.53.50.png

目錄結(jié)構(gòu)

屏幕快照 2018-01-24 下午7.54.37.png

系統(tǒng)默認(rèn)為我們生成SourceEditorCommand 文件,其中這個方法就當(dāng)做主入口,當(dāng)調(diào)用插件時會執(zhí)行這個方法。但是只能獲取到當(dāng)前編輯文件的內(nèi)容,不能獲取整個工程。

    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)
    }

核心代碼如下,大致邏輯是獲取當(dāng)前輸入的key,根據(jù)提前錄入的Map,查找對應(yīng)Value,并且替換當(dāng)前行內(nèi)容。

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..<arr.count{
                let insetStr = indentStr + arr[i]
                totalLines.insert(insetStr, at: curIndex + i)
            }
        }
    }

錄入界面

屏幕快照 2018-01-24 下午7.59.38.png

在主工程中,創(chuàng)建錄入界面,整體是個NSTableView,展示保存好的Map,雙擊某一行或者點擊添加按鈕,進(jìn)入編輯頁面,主要用NSTextField 實現(xiàn)

屏幕快照 2018-01-24 下午8.02.28.png

全局保存的Map 存儲在UserDefaults 里,但是宿主和擴(kuò)展共享數(shù)據(jù)的話,需要suiteName 相同才行,需要在App Group 里設(shè)置相同的key。

測試

  1. 先運(yùn)行主App,測試添加數(shù)據(jù)是否正常

  2. 運(yùn)行插件,選擇Xcode,會出來一個灰色的Xcode,隨便打開一個項目

屏幕快照 2018-01-24 下午8.07.17.png

輸入key,運(yùn)行插件,正確生成代碼。

屏幕快照 2018-01-24 下午8.07.58.png

也可以綁定快鍵鍵

屏幕快照 2018-01-24 下午8.10.08.png

使用

屏幕快照 2018-01-24 下午8.10.56.png

將app 拷入應(yīng)用程序里,并且將設(shè)置里Xcode 擴(kuò)展選上,重啟Xcode,就能在Editor 里使用啦

屏幕快照 2018-01-24 下午8.12.07.png

總結(jié)

插件主要參考了EasyCode,站在了巨人的肩膀上。但是目前EasyCode 好像Swift 不能用,因為媳婦開發(fā)用的純Swift,所以主要寫給她用的,目前插件的功能還很簡單,但是基本可以使用了,后續(xù)可以繼續(xù)優(yōu)化!

參考

WWDC2016
Xcode Source Editor Extension

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容