[閱讀難度:簡單]
SwiftPM(Swift Package Manager)是 2018 年推出供 Swift 開發(fā)者進(jìn)行包管理的工具,在這之前,老當(dāng)益壯的 Cocoapods 依舊占據(jù)著大量的市場,近年俘獲了越來越多開發(fā)者的 Carthage。蘋果依舊推出了 SwiftPM,現(xiàn)已距推出時過去了兩年的時間...
推出 SwiftPM 的原因
在 iOS 開發(fā)中,常見的包管理工具有 Cocoapods、Carthage。
CocoaPods 會自動為項目創(chuàng)建工作區(qū),并自動更新,功能強大,對新人非常友好,易于使用。但對工程來說,CocoaPods 需要在本地維護(hù)一個資源庫,且對工程干涉過深,對于一些項目模塊化需求實踐起來并不容易。
Carthage 是一款非常輕量級的工具,輕量級到?jīng)]有 CocoaPods 那些便捷的命令例如 $pod search,想知道三方庫是否支持 Carthage 還得去 github 上看庫是否支持。其勝在對項目幾乎無干涉,Carthage 工程文件下生成了專門管理依賴庫的 Carthage 文件,開發(fā)者只需將引入的庫拖入項目即可。
Carthage 支持二進(jìn)制編譯,極大的縮短了依賴庫在開發(fā)中編譯時間的開銷,這對中大型項目意義重大。 CocoaPods 雖然也可以進(jìn)行二進(jìn)制編譯,但需要依賴額外的工具庫,過程也相當(dāng)緩慢,個別庫的二進(jìn)制包可能會發(fā)生異常或臨到發(fā)版時報錯,到時候還得用非二進(jìn)制庫的方式打包。所以, Cocoapods 最好還是不要全部引入二進(jìn)制包,其實這也是 CocoaPods 的優(yōu)點之一,可以在開發(fā)中直接對源代碼進(jìn)行查看調(diào)試,而引入二進(jìn)制包的 Carthage 則不行。
那么有沒有能避免開發(fā)者去使用命令行甚至三方腳本來管理依賴庫,對項目 無侵入、簡單、易用、易調(diào)試,既能包含資源文件,又能針對 Swift 的 跨平臺 特點的包管理工具?工具本身用 Swift 寫的就更好了。

SwiftPM 中的一些概念
SwiftPM 是什么 :
SwiftPM 是管理 Swift 代碼分發(fā)的工具,與 Swift 構(gòu)建系統(tǒng)集成在一起,可以自動執(zhí)行依賴項的下載,編譯,鏈接,其本身也是一個庫,使用 Swift 編寫。
Modules(模塊) :
Swift 將代碼打包到模塊中,每個模塊都有單獨的命名空間,強制執(zhí)行訪問控制。
Packages(包) :
包由 Swift 源文件與配置文件(Package.swift)組成。配置文件定義了包的名稱及各種配置內(nèi)容,包可以有多個 Targets。
Products(產(chǎn)品) :
target 可以用來構(gòu)建庫或可執(zhí)行文件,庫包含可被其他 Swift 代碼導(dǎo)入的模塊??蓤?zhí)行文件可以直接由操作系統(tǒng)運行。
Dependencies(依賴關(guān)系) :
每個庫都可能依賴其他庫,以及依賴的具體版本。
SwiftPM 完全使用 Swift 編寫,與Swift有著非常好的契合性,不需要額外的殼子,也不需要第三方腳本來管理,可以將 SwiftPM 看做是工程引入的一個特殊的庫。
在 Xcode 中使用 SwiftPM
現(xiàn)在的 Xcode 已經(jīng)整合了 SwiftPM??稍陧椖康?Project 中看到 “Swift Packages” 一欄:

下面嘗試用 SwiftPM 來進(jìn)行包管理。
1. 安裝
略
SwiftPM 整合在 Xcode 中,對于 MacOS、iOS 開發(fā)者,安裝Xcode即可,其他平臺開發(fā)者可查閱官方文檔。
2. 導(dǎo)入
在 Project 的 Swift Package 欄,點擊下面列表的加號并填入需要引入庫的地址,例如 Alamofire 的地址:https://github.com/Alamofire/Alamofire,在經(jīng)過短暫的查找等待后,彈出了具體的導(dǎo)入配置界面:

導(dǎo)入規(guī)則 Rules 有三個選項: Version、Branch、Commit。
其中的 Version 可指定庫的版本更新規(guī)則:
Up to Next Major: 直到下一個大版本(5.2.2 ~ 6.00)Up to Next minor: 直到下一個中版本(5.2.2 ~ 5.3.0)Range: 限定版本范圍(自定義范圍)Exact: 指定固定版本(5.2.2)
沒有特殊需求就使用默認(rèn)選項,點擊 Next 按鈕,等待 Xcode 從網(wǎng)上拉取完畢。此處建議使用良好的網(wǎng)絡(luò)進(jìn)行拉取。
導(dǎo)入完成后,可以在 DriveData 下對應(yīng)的工程文件中看到新增了一個 SourcePackages 文件,在子文件 checkouts 下可以看到所有通過SwiftPM引入的依賴庫。
同時,可以看到工程內(nèi)新增了一欄 Swift Package Dependencies:

導(dǎo)入的庫跟手動下載庫后的文件結(jié)構(gòu)基本相同,只多了一點點...
3. 配置文件一覽
依賴庫的相關(guān)配置在 Pacakage.swift 中:

配置文件中采用聲明式語法創(chuàng)建了一個 Package 對象,Package 類來自 PackageDescription包 ,其主要作用是對包的描述。圖中 Almofire 的配置參數(shù)如下:
name: 包名
platforms: 支持的平臺
products: 編譯后的library
targets: 包中包含的targets,其中.testTarget是供測試的target
swiftLanguageVersions: 庫所使用的的 Swift 版本
除此之外,dependencies 參數(shù)為庫指定依賴的庫,SwiftPM 會自動加載所有依賴的庫。例如在引入 Realm 時,其依賴于 RealmCore, Package.swift 中可以看到該字段:
let package = Package(
//......
dependencies: [
.package(url: "https://github.com/realm/realm-core",.exact(Version(coreVersionStr)!)),
],
//......
在 SwiftPM 加載時會自動加載指定 url 處的 realm-core。加載完畢后可在 Swift Package Dependencies 中看到 RealmCore。
更多配置相關(guān)的參數(shù)可以進(jìn)入到 PackageDescription 庫查看(即 Package.swift 文件頭部 import 的 PackageDescription)
導(dǎo)入三方庫的配置文件不需要我們更改什么,如果是我們自己創(chuàng)建的庫給別人使用,或者直接將 SwiftPM 用來工程模塊化,就需要自定義 Package.swift 中的參數(shù)。
4. 使用導(dǎo)入的庫
在需要的地方引入庫即可:
import Alamofire
[擴(kuò)展]利用 Swift Package 進(jìn)行模塊化
假如需要將對系統(tǒng)類的一系列擴(kuò)展封裝成一個基礎(chǔ)庫,其他項目可通過SwiftPM依賴于它。
總共可分為兩步:
1.創(chuàng)建庫
- 打開 Xcode,新建一個
Swift Package。創(chuàng)建完畢后Xcode自動為我們生成好了庫的結(jié)構(gòu):

2)將代碼文件加入到該模塊的 Source文件夾 中。如果有多個文件夾,可分為多個 target 的方式在package.swift中進(jìn)行配置,若有依賴于其他庫可在 .dependencies字段后添加所依賴庫的git地址。
3)因為 SwiftPM 是針對所有 Swift 項目,沒有明確區(qū)分所限制的平臺。此處封裝的擴(kuò)展庫多針對于 UIKit ,在 Package.swift 文件中可以指定所支持的最低版本,但沒有僅允許或禁止某平臺的字段,目前參考其他三方庫的做法,在代碼文件中使用判斷運行環(huán)境:
#if os(iOS) || os(tvOS)
import UIKit
// 各種代碼
#endif
2. 發(fā)布更新到遠(yuǎn)端庫中
點擊菜單欄的 source control 標(biāo)簽下的
“New Git Repositories”創(chuàng)建本地git倉庫點擊Xcode左側(cè)git管理的標(biāo)簽,右鍵創(chuàng)建遠(yuǎn)程庫:

- 此處以 github 為例,只需登錄賬號就可以推送到github遠(yuǎn)端,也能推送到自己架設(shè)的內(nèi)網(wǎng)gitlab服務(wù)上。這里
別忘了版本號。
上傳成功后就可以通過 SwiftPM 在其他項目中導(dǎo)入我們的自定義庫了:
總結(jié)
SwiftPM 做到了 Cocoapods 的簡單易用 以及 Carthage 的輕量化無侵入,得益于其完全使用 Swift 編寫而成,完美與 Xcode 深度融合,不需要額外的殼子或腳本。又因 Swift 本身定位是一門跨平臺語言,所以 SwiftPM 不僅僅局限于本文中在 Xcode 中的使用。想要更深入了解跨平臺方面的小伙伴可自行查閱官方文檔,并結(jié)合其他三方庫的配置來學(xué)習(xí)。
