Swift Package ManagerTutorial 翻譯

Swift Package Manager 教程

翻譯自原文

是時(shí)候?qū)W習(xí)如何使用 Swift Package Manager 去處理外部依賴、在 macOS 和 linux 上創(chuàng)建你自己的 Swift 庫和 app 了。


Swift Package Manager 基礎(chǔ)

注意:由于 Apple 在 Swift 4 中為 Swift Package Manager 的 API 做了一個完全的重新設(shè)計(jì)(你可以閱讀相關(guān)更改的內(nèi)容),本教程并不適用于 Swift 3。 所以首先在我們開始之前,請?jiān)跈z查你的設(shè)備上的 Swift 版本。

swift --version
Apple Swift version 4.0.2 (swiftlang-900.0.69.2 clang-900.0.38)
Target: x86_64-apple-macosx10.9

創(chuàng)建 apps

所有困難的工作都可以交由 swift package 命令來完成。你可以在終端中輸入該命令查看可用的子命令。為了生成一個新的包,你應(yīng)該使用初始化命令。如果你不提供一個類型標(biāo)志,默認(rèn)情況下該命令將會生成一個庫,但這一次我們想要生成一個可執(zhí)行的應(yīng)用。

swift package init --type executable 
swift build 
swift run my-app

編譯器可以在 swift build 命令的幫助下構(gòu)建你的源文件。該可執(zhí)行文件將會被放置在 .build/ 目錄下的某個地方,如果你使用 swift run my-app 命令來運(yùn)行剛剛創(chuàng)建的應(yīng)用,你應(yīng)該呢個看到基本的 'Hello, world!' 消息。

祝賀你成功生成了你的第一個命令行 Swift 應(yīng)用程序!

現(xiàn)在你應(yīng)當(dāng)來做一些切實(shí)的編碼了。通常而言你的 Swift 源文件應(yīng)該在 Sources 目錄下, 然而你可能想要為你的 app 創(chuàng)建一些可復(fù)用的部分。所以讓我們通過創(chuàng)建一個全新的庫來為這個場景做準(zhǔn)備吧。

生成一個 Library

我們依舊從從初始化命令開始,但這次我們不指定 init 的類型了。實(shí)際上我們可以鍵入 swift package init --type library 但這需要鍵入很多單詞。 ?? 另外由于我們正在生成一個庫, SPM 將會給我們提供一些基本的測試,讓我們使用 swift test 命令來運(yùn)行它們吧。

swift package init
swift test

如果你此時(shí)檢查文件結(jié)構(gòu),你會在 Tests 下看到一個單元測試的例子,而不會在 source 中找到 main.swift 文件。

現(xiàn)在你有了一些基礎(chǔ)了。你有一個示例程序和一個 library, 讓我們在 Swift Package Manager Manifest API 的幫助下將它們鏈接在一起吧。

The Manifest API(清單 API) - Package.swift

每一個 SPM 包內(nèi)都有一個 Package.swift 清單文件(manifest file). 在清單文件中你可以定義你的全部依賴、targets 甚至為你的工程定義指定的源文件.在本節(jié)我會教你清單文件 (manifest file) 的一些基礎(chǔ)內(nèi)容.

工具版本

首先如果你想支持新的 manifest file 的格式 (換言之, Swift 4 版本) , 你得以注釋的方式在你的 manifest 文件設(shè)置 swift-tools-version.

// swift-tools-version:4.0

現(xiàn)在你已經(jīng)準(zhǔn)備好在全新的 manifest API 下工作了!

依賴

讓我們先通過在 Package.swift 文件中創(chuàng)建一個新的包依賴 (package dependency) 來為主程序添加一個依賴庫. 第一個參數(shù)是一條包 url 字符串,可以是本地文件路徑也可以是遠(yuǎn)程 url (通常是一個 github 倉庫鏈接). 注意, 你還應(yīng)當(dāng)將你的依賴添加到 targets 中. 通常而言包的特定名稱 (包名) 已經(jīng)在該 library 的 manifest 文件中定義了.

// swift-tools-version:4.0

import PackageDescription

let package = Package(
    name: "my-app",
    dependencies: [
        .package(url: "../my-lib", .branch("master")),
    ],
    targets: [
        .target(
            name: "my-app",
            dependencies: ["my-lib"]
        ),
    ]
)

如果你現(xiàn)在運(yùn)行 swift build 你將編譯源文件失敗. 那是因?yàn)?SPM 僅會工作在 git 倉庫下. 這就意味著你需要為你的 library 創(chuàng)建一個 git 倉庫. 讓我們移動到該目錄并執(zhí)行如下命令:

git init
git add .
git commit -m 'initial'

你也應(yīng)當(dāng)標(biāo)記我們指定的包依賴的分支。你可以使用 version 號,甚至也可以用 commit hashes 。所有可用的選項(xiàng)都很好的被寫在了 manifest api redesign proposal 文檔中。

現(xiàn)在讓我們回到應(yīng)用目錄并使用 swift package update 命令來更新以來。這次它就能夠獲取、克隆并成功搞定我們的依賴了。

你可以構(gòu)建并運(yùn)行,然而我們忘了設(shè)置我們 library 中結(jié)構(gòu)體的訪問級為 public, 所以從該 API 中看不到任何東西。

public struct my_lib {
    public var text = "Hello, World!"

    public init() {}
}

讓我們來做一些修改并將其提交到該 library 的主分支上。

git add .
git commit -m 'access level fix'

你已經(jīng)準(zhǔn)備好在 app 中使用該 lib 了,修改 main.swift file 如下。

import my_lib

print(my_lib().text)

再一次更新依賴,這次我們來構(gòu)建一個 release 構(gòu)建。

swift package update
swift build -c release
swift run -c release

通過 -c--configuration 標(biāo)識你可以生成一個 release 構(gòu)建。

Products 與 targets

默認(rèn)情況下, SPM 與下列 targets 目錄一起工作:

Regular targets: package root, Sources, Source, src, srcs.
Test targets: Tests, package root, Sources, Source, src, srcs.

這就表明,如果你在這些目錄下創(chuàng)建 .swift 文件,這些源文件將根據(jù)文件路徑被編譯或測試。另外,生成的 mainfest 文件將僅僅包含一份構(gòu)建 target (像 Xcode targets一樣) , 但有時(shí)候你想要從同一個 bundle 中創(chuàng)建多個 apps 或 libraries. 讓我們稍微修改下我們的 Package.swift, 并看看如何能創(chuàng)造一個全新的 target.

// swift-tools-version:4.0

import PackageDescription

let package = Package(
    name: "my-app",
    dependencies: [
        .package(url: "../my-lib", .branch("master")),
        .package(url: "https://github.com/kylef/Commander", from: "0.8.0"),
    ],
    targets: [
        .target(
            name: "my-app",
            dependencies: ["my-lib"]
        ),
        .target(
            name: "my-cmd",
            dependencies: ["Commander"],
            path: "./Sources/my-cmd",
            sources: ["main.swift"]
        ),
    ]
)

我們剛剛從 github 創(chuàng)建了一個新的依賴 和一個在 Sources/my-cmd 目錄下只含有 main.swift 文件的全新的 target. 現(xiàn)在讓我們創(chuàng)建這個目錄并為這個新的 app 添加一些源碼.

import Foundation
import Commander

let main = command { (name:String) in
    print("Hello, \(name.capitalized)!")
}

main.run()

使用 swift build 編譯這個工程并用一個額外的 name 參數(shù)運(yùn)行這個新創(chuàng)建的 app. 希望你能看到的輸出如下:

swift run my-cmd guest
// Hello, Guest!

因此我們剛剛創(chuàng)建了一個全新的可執(zhí)行的 target, 但如果你想將你的 targets 暴露給其他的 packages , 你應(yīng)當(dāng)也將它們定義為 products. 如果你打開這個 library 的 manifest 文件, 你會看到里面有個從該 library target 定義 target 字段. 通過這種方式, 包管理器可以根據(jù)給定的 product name 鏈接 product 依賴.

注意: 你可以定義 static 或 dynamic 的 libraries. 但推薦使用 automatic , 這樣可以讓 SPM 決定合適的鏈接.

// swift-tools-version:4.0
import PackageDescription


let package = Package(
    name: "my-lib-package",
    products: [
        .library(name: "my-lib", targets: ["my-lib"]),
        //.library(name: "my-lib", type: .static, targets: ["my-lib"]),
        //.library(name: "my-lib", type: .dynamic, targets: ["my-lib"]),
    ],
    dependencies: [
        // .package(url: /* package url */, from: "1.0.0"),
    ],
    targets: [
        .target(
            name: "my-lib",
            dependencies: []),
        .testTarget(
            name: "my-libTests",
            dependencies: ["my-lib"]),
    ]
)

部署目標(biāo)(Deployment target), 其他 build flags

有時(shí)候你需要為你的包指定部署的 target. 現(xiàn)在 Swift Package Manager 已經(jīng)能做到了 (已經(jīng)有 一段時(shí)間了). 你只需要在構(gòu)建階段為編譯器提供一些額外的參數(shù)就行了.

swift build -Xswiftc "-target" -Xswiftc "x86_64-apple-macosx10.12"

定義構(gòu)建的 flags 也是可行的.

swift build -Xswiftc "-D" -Xswiftc "DEBUG"

現(xiàn)在在你的源碼里面你可以檢查 DEBUG 標(biāo)志的存在了.

#if DEBUG
    print("debug mode")
#endif

如果你想了解更多關(guān)于構(gòu)建過程的內(nèi)容, 只需要鍵入 swift build --help 你就可以看到該構(gòu)建命令可用的選項(xiàng).

還有一件事

你可以通過 Swift Package Manager 來生成 Xcode Projects。

swift package generate-xcodeproj

這就是 SPM 的簡單介紹了。實(shí)際上我們不僅僅介紹了 Swift Package Manager 的基礎(chǔ)知識,也稍微拓展了一些,現(xiàn)在你應(yīng)該對 targets、products 以及大部分可用的命令比較熟悉了,但仍然還有很多需要學(xué)習(xí)。所以如果你想對這個 amazing 的工具了解更多,這里還有一些非常棒的資源等著你去瀏覽。 Enjoy! ??

另外,本教程的源碼可以在 github 上獲取。

拓展閱讀

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,213評論 4 61
  • 春天來了,然而我并沒有帶春天的衣服,這個月的零花錢也花的差不多了,只夠生活。我就想讓媽媽支援我一點(diǎn),買個外套。 晚...
    丹陽world閱讀 391評論 0 0
  • 7組65號梁小美 一直是葉老師和時(shí)間管理的崇拜者,偶然得到了葉老師的《善用時(shí)間》,又虔誠求得了葉老師的親筆簽名,更...
    G192小美閱讀 240評論 0 0
  • 昨日,期待已久的李宇春《野蠻生長》的第一張EP《野》的第一首主打歌《存在感》正式來襲?!霸茖臃屎瘢斓睾軐?,瘋狂愛...
    三毛的撒哈拉閱讀 467評論 2 1
  • 努力曾把生活過成詩 卻忘記生活是由 90%的茍且 9....
    今析何兮閱讀 293評論 2 3

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