Swift 包管理器教程

來源:互聯網
上載者:User

標籤:工作原理   方法   依賴   des   開始   運行   結構   生態   country   

原文: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。你會看到這個命令的介紹。你將使用這幾個命令:

  1. swift package init ,建立新包
  2. swift package update ,更新一個包的依賴
  3. swift package generate-xcodeproj ,為包產生 Xcode 項目

要學習 Swift 包管理器,我們將編寫一個命令列 app,用一個庫列印出所有國家的國旗字元。首先我們會建立一個可執行包。這種包也就是命令列 app。Swift web app 也屬於這種類別。

通過以下命令,建立一個名為 Flag 的可執行包:

mkdir Flagcd Flagswift 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’/>

  1. Package.swift 包含包的描述資訊,還包含包的依賴。
  2. Sources/,如名稱所示,用於存放你的 Swift 源檔案。裡面會產生一個 main.swift 檔案。這是應用程式的入口。現在,它只會列印 hello world。
  3. Tests/ ,包含單元測試,你可以用 XCText 編寫這些測試。待會你會寫測試代碼。

回到終端視窗,運行:

swift build

這會編譯包並在 .build/debug/ 建立一個可執行檔 Flag。運行這個 app,只需要:

.build/debug/Flag

你會在螢幕上看到 Hello,world!

恭喜你!你建立和編譯通過了你的第一個 Swift 包!

建立庫

要真正能夠產生某個國家的國企字元,我們需要編寫一個名為 Atlas 的庫。然後在你的 Flag app 中調用這個庫。

切到 Flag 包之外的目錄,通過終端命令建立一個庫:

cd ..mkdir Atlascd Atlasswift 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: String  public 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 Atlasclass 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.value  return 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 initgit 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 build

Swift 包管理器將抓取、編譯庫並將之串連到你的可執行包。現在的檔案夾結構將是這個樣子:

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 ../Atlasswift 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 ../Flagswift 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 包管理器教程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.