Swift 包管理器教程
原文:An Introduction to the Swift Package Manager
作者: Mikael Konutgan
譯者:kmyhy
Swift 包管理器的正式發布是隨著 Swift3.0 一起發布的,它是一個用于構建能夠運行在 macOS 和 Linux 上的 Swift 庫和 app 的新方法。它能夠幫助你管理依賴,讓你輕松構建、測試和運行你的 Swift 代碼。
Swift 包管理器有助于極大地改進 Swift 生態系統,讓 Swift 更容易使用、部署到沒有 Xcode 的平臺上,比如 Linux。Swift 包管理器還能解決在使用多個相互依賴的庫時的“依賴地獄”的問題。
重要的一點是,因為 Swift 3 的原因,Swift 包管理器只能在 host 平臺上編譯。換句話說,你無法編譯、使用 iOS、watchOS 和 tvOS 上的包。
讓我們開始吧!
開始
在開始之前,確認你已經安裝了 Swift 3.0 以上。Swift 3 內置在 Xcode8+,因此如果你已經安裝了 Xcode8 或以上,你就可以開始本教程。當然實際上你并不需要用 Xcode 去完成本教程,你可以直接從 swift.org 下載安裝 Swift 3。
打開終端窗口,輸入 swift package。你會看到這個命令的介紹。你將使用這幾個命令:
要學習 Swift 包管理器,我們將編寫一個命令行 app,用一個庫打印出所有國家的國旗字符。首先我們會創建一個可執行包。這種包也就是命令行 app。Swift web app 也屬于這種類別。
通過以下命令,創建一個名為 Flag 的可執行包:
mkdir Flag cd Flag swift package init --type executable在運行 swift package init 命令行時,切換到 Flag 目錄是關鍵的,因為 Flag 將作為包名。你會看到輸出中會顯示一些文件和文件夾,它們是自動生成的。現在來熟悉一下項目結構:
https://koenig-media.raywenderlich.com/uploads/2016/12/Flag-%E2%94%9C%E2%94%80%E2%94%80-Package.swi_.png’ width= ‘300’/>
回到終端窗口,運行:
swift build這會編譯包并在 .build/debug/ 創建一個可執行文件 Flag。運行這個 app,只需要:
.build/debug/Flag你會在屏幕上看到 Hello,world!
恭喜你!你創建和編譯通過了你的第一個 Swift 包!
創建庫
要真正能夠生成某個國家的國企字符,我們需要編寫一個名為 Atlas 的庫。然后在你的 Flag app 中調用這個庫。
切到 Flag 包之外的目錄,通過終端命令創建一個庫:
cd .. mkdir Atlas cd Atlas swift package init --type library包管理器會創建幾個文件和文件夾。
https://koenig-media.raywenderlich.com/uploads/2017/01/atlas-library-structure.png’ width=’300’/>
這次,main.swift 會被 Atlas.swift 所替代。這個文件以及在 Sources/ 目錄下的文件都會被導入到這個庫中。實際上,庫和可執行包的區別就在于有沒有 main.swift。
這次我們需要用一個測試。用 swift test 來運行這個測試。Swift 包管理器會編譯庫并運行測試。
注意:你會在 Tests/ 目錄下看到 LinuxMain.swift 文件,在 AtlasTests 的測試案例類中還有一個 allTests 屬性。對于要在 Linux 上運行 XCTest 測試而言,這兩者都是必須的。Linux 沒有 O-C 運行時,而 O-C 運行時會自動查找以 test 開頭的方法并運行它。每當添加一個測試方法,你都需要修改這個 allTests 屬性,每當添加一個新的測試案例類,你都需要修改 LinuxMain.swift。
打開 Atlas.swift 修改內容為:
public struct Country {public let code: Stringpublic init(code: String) {self.code = code.uppercased()}public var emojiFlag: String {return "\u{1f1f5}\u{1f1f7}"} }這里我們實現了一個 Country 結構,它通過一個 ISO 國別代碼進行初始化。emojiFlag 屬性根據國別代碼返回對應的國旗字符。現在,你需要編寫測試。
注意每個方法和屬性都標記為公有的,這樣它的每個成員對于使用這個庫的代碼來說都是課件的:]
打開 AtlasTests.swift,編輯內容為:
import XCTest @testable import Atlas class AtlasTests: XCTestCase {func testAustria() {XCTAssertEqual(Country(code: "AT").emojiFlag, "\u{1f1e6}\u{1f1f9}")}func testTurkey() {XCTAssertEqual(Country(code: "TR").emojiFlag, "\u{1f1f9}\u{1f1f7}")}func testUnitedStates() {XCTAssertEqual(Country(code: "US").emojiFlag, "\u{1f1fa}\u{1f1f8}")} }extension AtlasTests {static var allTests : [(String, (AtlasTests) -> () throws -> Void)] {return [("testAustria", testAustria),("testTurkey", testTurkey),("testUnitedStates", testUnitedStates)]} }這里實現了 3 個測試。我們創建了 3 個不同的國籍,然后斷言它們是否擁有正確的 emoji 國旗字符。
運行測試:
swift test你會看到 3 個測試被運行,但全部失敗。這說明我們還有很多事情要干啊 :]
現在我們測試失敗了,我們要讓它們通過測試。
emoji 國旗的工作原理非常簡單:傳入一個國家代碼,比如 AT,然后將每個字符轉換成設為的地區指示標志。例如, �� 和 ��。然后將二者組合在一起,你就會得到 emoji 國旗!
https://koenig-media.raywenderlich.com/uploads/2017/01/ragecomic_flags.png’ width=’600’/>
回到 Atlas.swift 為 Country 結構增加一個方法:
func regionalIndicatorSymbol(unicodeScalar: UnicodeScalar) -> UnicodeScalar? {let uppercaseA = UnicodeScalar("A")!let regionalIndicatorSymbolA = UnicodeScalar("\u{1f1e6}")!let distance = unicodeScalar.value - uppercaseA.valuereturn UnicodeScalar(regionalIndicatorSymbolA.value + distance) }這里,我們利用了字母和區域指示標志在 Unicode 表中的值都是連續排列的原理。比如 A 是 65,B 是 66,而 �� 是 127462,�� 就是 127463。如果將字符 P 轉換成區域指示標志,需要計算出 A 到 P 的值相差多少,然后將 ��加上這個差值就得到 ��。
這是最難的部分。寫好這個方法后,剩下的事情就簡單了。將 emojiFlag 屬性定義修改為:
public var emojiFlag: String {return code.unicodeScalars.map { String(regionalIndicatorSymbol(unicodeScalar: $0)!) } .joined() }我們將國家代碼的每個字母放到數組中,然后將每個字母轉換成對應的區域指示標志,然后將它們連在一起。這就得到了國旗!
運行測試,3 個測試都通過了。
接下來將代碼提交到 Git,并標記一個本號。因為這是我們的第一個版本,我們可以將版本標記為 1.0.0。
執行下列命令,創建 Git 存儲庫并標記版本:
git init git add . git commit -m "Initial commit" git tag 1.0.0創建可執行包
現在你已經準備好 Flag 庫,我們可以將它添加為 Flag 可執行包的依賴。
回到 Flag 目錄,打開 Package.swift 文件。它目前是這個樣子:
import PackageDescriptionlet package = Package(name: "Flag" )每個 Swift 包都有一個類似的 PackageDescription。最重要的參數是 dependencies 參數。
將包描述修改為這樣:
let package = Package(name: "Flag",dependencies: [.Package(url: "../Atlas", "1.0.0")] )這里,我們聲明 Flag 包擁有一個依賴,這個依賴的 URL 是 ../Atlas,版本是 1.0.0。
版本號應該使用語義上的版本號。簡單說,就是類似于 MAJOR.MINOR.PATCH 這樣的版本號。MAJOR 版本表示的是不向后兼容的修改,MINOR 版本表示向后兼容的修改,PATCH 版本是 bug 的修復。關于語義版本,細節可參考 這里。
大部分情況下,你只想讓新版本在 bug 修復和小版本改進上做修改。幸好,Swift 包管理器允許我們這樣做。將包描述修改為:
let package = Package(name: "Flag",dependencies: [.Package(url: "../Atlas", majorVersion: 1)] )包管理器提供了你在更新庫時想精確控制的版本。請參考這里。
編譯包:
swift buildSwift 包管理器將抓取、編譯庫并將之連接到你的可執行包。現在的文件夾結構將是這個樣子:
https://koenig-media.raywenderlich.com/uploads/2017/01/flag-structure.png’ width=’300’/>
你會看到 Swift 包管理器已經細心地根據你的要求將 1.0.0 版本安裝到項目中了。打開 main.swift 文件,編輯內容如下:
import Atlaslet arguments = CommandLine.argumentsif arguments.count != 2 {print("USAGE: flag [iso country code]") } else {let code = arguments[1]let country = Atlas.Country(code: code)print(country.emojiFlag) }這里,我們導入了 Atlas 庫,根據命令行參數的第一個參數,打印出對應的國旗 emoji。如果缺少參數,我們會打印命令幫助。
編譯運行 app:
swift build ./.build/debug/Flag US你在終端窗口中看到了美國國旗!
在你和你的 app 玩得不亦樂乎的時候,我們該來打包它 了。最后編譯一下 app,這次需要加上 release 優化參數:
swift build --configuration release現在你可以這樣運行你的 release 版 app 了:
./.build/release/Flag PR你可以將 ./.build/release/Flag 文件打包壓縮,然后分享給你的朋友、家人或其它人了 :]
用包管理器生成 Xcode 項目
老舊的命令行和文本編輯器很酷,但你可能是一個 iOS 或 macOS 程序員,你使用的是 Xcode。別擔心——大部分工作 Xcode 都可以做得很好。
回到 Atlas 包下面,生成一個 Xcode 項目:
cd ../Atlas swift package generate-xcodeproj這會生成一個 Atlas.xcodeproj 文件。你可以用 Xcode 打開這個項目,像其他 Xcode 項目一樣編譯包和運行測試。
https://koenig-media.raywenderlich.com/uploads/2017/01/xcode-650x357.png’ width= ‘600’/>
同樣的方法可以用在 Flag 包上。在 Flag 文件夾下面執行 swift package generate-xcodeproj 命令,生成 Flag.xcodeproj。
cd ../Flag swift package generate-xcodeproj用 Xcode 打開項目,確認 Flag 可執行目標是否選中,它顯示一個小的終端窗口的圖標。現在你也可以編譯和運行這個包了。
為了指定可執行命令的參數,請進入 Product\Scheme\Edit Scheme… 窗口,選擇 Run\Arguments ,在 Arguments Passed On Launch 中添加一個參數比如 US:
https://koenig-media.raywenderlich.com/uploads/2017/01/Flag_xcodeproj-650x361.png’ width=’600’/>
注意,Xcode 無法添加和編譯依賴,因此你無法完全離開命令行。
結束
你可以從這里下載完成的 Swift 包管理器項目。
你還可以參考Swift 官網關于包管理器的章節。
關于包描述選項的最新文檔,請參考github。
關于 Swift 4 的包管理器修改方向,你可以參考 Swift 演進路線圖的郵件列表。
你還可以參考IBM 的 Swift Package Catalog,它可以幫助你找到可以用在你項目中的新包。
在 Swift 包管理器能夠支持非主機平臺之前,你仍然不得不使用 Cocoapods 或 Carthage 來構建 iOS、watchOS 和 tvOS app。
留作今天的作業,你可以將你的庫推到 GitHub,然后在 Atlas 中使用它的遠程依賴。提示:只需要將 dependency 的 url 參數修改為 GitHub URL。
嘗試添加新的功能,比如當沒有提供任何參數時,列出所有國家的名字和國旗。提示:你將需要用到 Locale.isoRegionCodes。
在 Atlas 庫中實現你的新功能,然后創建新的版本,比如 1.1.0,然后在 Flag 中使用這個新版本。確認你在包描述中使用了新版本,然后通過 Swift 包管理器將依賴升級到新版本。
將你的答案公布到下面的留言中,祝你開心!
總結
以上是生活随笔為你收集整理的Swift 包管理器教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下jetty报java.lan
- 下一篇: 悦虎144固件,华强北二代悦虎144固件