Swift 模塊化項(xiàng)目結(jié)構(gòu)最佳實(shí)踐

原文鏈接:http://liuduo.me/2017/05/22/moduleproject/
微博:@劉鐸Derek

這篇文章沒(méi)有技術(shù),只講怎么用 Xcode 組織項(xiàng)目結(jié)構(gòu)。

開(kāi)篇

寫(xiě)了這么多年的代碼,目前覺(jué)得最好的構(gòu)造項(xiàng)目結(jié)構(gòu)的方式就是 模塊化。

模塊化在 Objective-C 的項(xiàng)目中可能比較難搞起來(lái),但是在 Swift 項(xiàng)目中就游潤(rùn)有余了,因?yàn)?Swift 有著天生 Module 的概念,和它的訪問(wèn)控制修飾符。

小型項(xiàng)目搞模塊化意義可能不大,對(duì)于中型和大型的項(xiàng)目,模塊化以后,縱向分層橫向分模塊,模塊間解耦,訪問(wèn)控制,依賴(lài)注入,依賴(lài)倒轉(zhuǎn),在開(kāi)發(fā)過(guò)程中就能自然而然的寫(xiě)出來(lái),省去以后重構(gòu)的苦惱。

大家都知道,Xcode 主要是用 WorkspaceProject 來(lái)組織項(xiàng)目結(jié)構(gòu)的,一個(gè)工程只能有一個(gè) Workspace,一個(gè) Workspace 中可以有任意多個(gè) Project。

而模塊化的方式就是把各個(gè)業(yè)務(wù)功能拆分成模塊(Framework),然后主工程負(fù)責(zé)把這些業(yè)務(wù)模塊串聯(lián)起來(lái)構(gòu)成一個(gè)完成的 App。

工程結(jié)構(gòu)

在一個(gè)項(xiàng)目里,有一個(gè) Workspace,其中有很多個(gè) Project,主工程是一個(gè) Project,每個(gè)業(yè)務(wù)模塊也都是一個(gè) Project。

效果是這樣的:

在工程中,每添加一個(gè)新模塊的時(shí)候,通過(guò)點(diǎn)擊左下角的 + 來(lái)創(chuàng)建,選擇 Framework 類(lèi)型:

路徑選擇到 Modules 目錄下。

如果你覺(jué)得需要的話,可以對(duì) Modules 目錄下的這些 Project 再分目錄。

如何創(chuàng)建 Workspace?

如果是從一個(gè)新工程開(kāi)始創(chuàng)建,可以在 Xcode 中選擇:File -> New -> Workspace... 創(chuàng)建,然后再在創(chuàng)建好的 Workspace 中添加主工程。

如果你是用了 CocoaPods,在第一次 pod install 時(shí),CocoaPods 會(huì)幫你創(chuàng)建好 Workspace。

依賴(lài)配置

對(duì)于每一個(gè)模塊 xcodeproj,都需要在這里嚴(yán)格配置好它的依賴(lài)。

同屬于一個(gè) WorkspaceProject 們,可以方便的互相配置依賴(lài),Xcode 可以很好的處理好這個(gè)依賴(lài)。

配置了依賴(lài)以后的 Framework,在編譯時(shí) Xcode 會(huì)先編譯它依賴(lài)的那些 Framework, 確保這個(gè) Framework 可以順利配置成功。

用這種項(xiàng)目結(jié)構(gòu)時(shí),依賴(lài)必須嚴(yán)格配置正確,否則即使在模擬器或真機(jī)運(yùn)行時(shí)沒(méi)有問(wèn)題,打包的時(shí)候一定會(huì)出現(xiàn)問(wèn)題。這樣當(dāng)想知道一個(gè)模塊依賴(lài)了哪些模塊時(shí),可以直觀的從這里查看到。

為每一個(gè)模塊添加 Demo 和單元測(cè)試

由于一個(gè)模塊是一個(gè)單獨(dú)的 Project,可以在里面方便的添加 Demo 和單元測(cè)試的 Target。

點(diǎn)坐下的 + 即可添加。

CocoaPods

如果你的某一個(gè)模塊需要依賴(lài) CocoaPods 中的庫(kù),CocoaPods 本身也很好的支持了這個(gè)需求。

Podfile 文件中添加一個(gè) target 的配置即可。

target 'Slide' do
    project "Modules/Slide/Slide"
    pod 'SDWebImage', '3.8.2'
    pod 'SDWebImage/WebP'
end

Carthage

使用 Swift 語(yǔ)言的項(xiàng)目也會(huì)經(jīng)常用到 Carthage。一般都是直接依賴(lài) Carthage/Build 中編譯好的 .framework 文件,然后類(lèi)型為 App 的 Project,要配置 copy-framework 腳本,類(lèi)型為 Framework 的 Project,要在 Build Phases 中添加一個(gè) Copy Files Phases,這是官方文檔中的說(shuō)法。

但是在我們這種項(xiàng)目結(jié)構(gòu)中,如果為每個(gè)模塊都配置 Copy Files Phases,會(huì)導(dǎo)致打出來(lái)的包中,每個(gè)模塊的 Framework 都包含了它依賴(lài)的那些 Framework,導(dǎo)致包大小非常大,因?yàn)槔锩姘朔浅6嗟闹貜?fù) Framework。

于是我們?cè)?Workspace 中又建立的一個(gè)目錄叫 CarthageFrameworks,然后把 Carthage/Checkout 目錄中的那些 .xcodeproj 文件拖到這個(gè) CarthageFrameworks 目錄中,效果如下:

這樣不僅解決了打包重復(fù)包含 Framework 的問(wèn)題,還能方便的查看 Carthage 引入的庫(kù)的代碼,并且方便的設(shè)斷點(diǎn)調(diào)試。

列舉一下好處

  • 模塊化,各模塊之間獨(dú)立,職責(zé)清晰
  • 開(kāi)發(fā)過(guò)程中會(huì)自然強(qiáng)制你考慮模塊間解耦,訪問(wèn)控制,依賴(lài)注入,依賴(lài)倒轉(zhuǎn)等問(wèn)題
  • 依賴(lài)必須嚴(yán)格配置,方便查看和梳理依賴(lài)
  • 每個(gè) Project 都有一個(gè) xxx.xcodeproj文件,這個(gè)文件是最常出現(xiàn)沖突的文件了,而且這個(gè)文件的沖突還往往很難解決,模塊化分開(kāi)后,各個(gè)模塊都有單獨(dú)的 xxx.xcodeproj 文件,大大降低發(fā)生沖突的概率。
  • 模塊擁有自己的 Targets 空間,方便創(chuàng)建 Demo 和單元測(cè)試
  • 如果想把模塊做成單獨(dú)的 git 倉(cāng)庫(kù),也非常的方便
  • 方便進(jìn)行 Carthage 引入的庫(kù)的調(diào)試
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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