基于SwiftSyntax寫一個命令行工具檢測Xcode項目中不用的圖片資源

其實已經(jīng)有一個不錯的用Swift寫的命令行工具檢測不用的圖片資源了,就是喵神的FengNiao语稠,至于為什么要再寫一個呢,主要是為了學(xué)習(xí)SwiftSyntax输涕,前段時間我寫了篇文章簡單的介紹了SwiftSyntax慨畸,文章在這里SwiftSyntax詳解,對SwiftSyntax不熟悉的可以先看看型奥。

項目在這里UnusedResources,下面來簡單介紹一下原理厢汹。

1. 找到項目中所有的圖片資源

我這里找的圖片資源有以下幾種:

let imageExtensions: [String] = ["png", "jpg", "gif", "pdf"]

這里不得不提以下Homebrew的作者mxcl開源的庫Path,這個庫真的很好用界弧。我們先定義一個方法來來查找所需擴展名的文件

func recursiveFiles(withExtensions exts: [String], at path: Path) throws -> [Path] {
    if path.isFile {
        if exts.contains(path.extension) {
            return [path]
        }
        return []
    } else if path.isDirectory {
        var files: [Path] = []
        for entry in try path.ls() {
            let list = try recursiveFiles(withExtensions: exts, at: entry.path)
            files.append(contentsOf: list)
        }
        return files
    }
    return []
}

找到所有的圖片資源就只要下面簡單的一段代碼就可以了

var images: [Path] = try recursiveFiles(withExtensions: imageExtensions, at: path)

2. 查看項目中源代碼文件

找到源代碼文件

var files: [Path] = try recursiveFiles(withExtensions: ["swift", "h", "m", "mm"], at: path)

這里就需要用到SwiftSyntax垢箕,我們定義一個StringVisitor遍歷語法樹兑巾,提取字符串并判斷是否和圖片名稱一樣,一樣就說明圖片被使用了帅掘。

我們一個簡單的swift代碼的語法樹,可以用xcrun swiftc -frontend -emit-syntax ./Cat.swift | python -m json.tool命令查看源代碼語法樹結(jié)構(gòu)修档,但是還是比較復(fù)雜府框,包含import庫的部分,所以我選擇用Swift AST Explorer院峡,這個是基于SwiftSyntax實現(xiàn)系宜,語法樹更簡潔。

屏幕快照 2019-11-06 下午6.44.40.png

我們只要拿到StringSegmentSyntax的內(nèi)容就好了实抡,然后和圖片進行對比欢策,和圖片一樣赏淌,就表示圖片被使用到了。

public struct StringVisitor: SyntaxVisitor {
    
    public var images: [Path] = []
        
    public init(_ images: [Path]) {
        self.images = images
    }
    
    // Ignore string interpolated literal because it's too complex to compare
    public mutating func visit(_ node: StringLiteralExprSyntax) -> SyntaxVisitorContinueKind {
        guard node.segments.count == 1 else {
            return .skipChildren
        }
        return .visitChildren
    }
    
    public mutating func visit(_ node: StringSegmentSyntax) -> SyntaxVisitorContinueKind {
        let text = node.content.text
            .trimmingCharacters(in: .whitespacesAndNewlines)
        guard !text.isEmpty else {
            return .skipChildren
        }

        images = images.filter { $0.basename(dropExtension: true) != text }

        return .skipChildren
    }
 }

OC和Swift的語法書稍微有點不一樣俺孙,所以我們可以得到所有的TokenSyntax,然后找到類型是stringLiteral的荣茫,這里我處理比較簡單场靴,直接判斷stringLiteral是否包含圖片名稱,如果包含就表示圖片被使用了旨剥。

屏幕快照 2019-11-06 下午6.39.09.png

所以我們再給StringVisitor添加一個方法

// for Objective-C
    public mutating func visit(_ token: TokenSyntax) -> SyntaxVisitorContinueKind {
        switch token.tokenKind {
        case .stringLiteral(let text):
            images = images.filter { !text.contains($0.basename(dropExtension: true)) }
        default:
            break
        }
        
        return .visitChildren
    }

3. 查看XML文件

let xmlExtensions: [String] = ["xib", "storyboard"]
var xmlFiles: [Path] = try recursiveFiles(withExtensions: xmlExtensions, at: path)

這里需要用到XMLParser找到attributeDict中key為“image”的value魄咕,如果和圖片名稱一樣就表示圖片被使用了。

4. Makefile

使用Makefile來build項目哮兰,自動將生成的unused-resources拷貝到/usr/local/bin中梢什。

5. 總結(jié)

水文一篇,最近在研究編譯相關(guān)的知識囤躁,進展十分緩慢荔睹,心累。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宵距,一起剝皮案震驚了整個濱河市吨拗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌劝篷,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件像鸡,死亡現(xiàn)場離奇詭異只估,居然都是意外死亡志群,警方通過查閱死者的電腦和手機锌云,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門宾抓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人石洗,你說我怎么就攤上這事紧显。” “怎么了孵班?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵篙程,是天一觀的道長。 經(jīng)常有香客問我虱饿,道長,這世上最難降的妖魔是什么渴肉? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任仇祭,我火速辦了婚禮,結(jié)果婚禮上乌奇,老公的妹妹穿的比我還像新娘眯娱。我一直安慰自己,他們只是感情好困乒,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布娜搂。 她就那樣靜靜地躺著迁霎,像睡著了一般考廉。 火紅的嫁衣襯著肌膚如雪携御。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天涮坐,我揣著相機與錄音,去河邊找鬼袱讹。 笑死昵时,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的壹甥。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼浦译,長吁一口氣:“原來是場噩夢啊……” “哼溯职!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起渤弛,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤甚带,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鹰贵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡籽前,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年枝哄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挠锥。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡蓖租,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蓖宦,到底是詐尸還是另有隱情,我是刑警寧澤稠茂,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布主慰,位于F島的核電站,受9級特大地震影響共螺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜藐不,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望涎嚼。 院中可真熱鬧挑秉,春花似錦、人聲如沸犀概。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至捂掰,卻和暖如春敢会,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸥昏。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留敛腌,地道東北人像樊。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓颤霎,卻偏偏與公主長得像涂滴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子缔杉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351