跳至內容

遷移 Swift 套件

Swift Package Manager 最初是作為 Swift 程式碼的相依性管理工具出現,卻意外地開始承擔專案管理與支援 Objective-C 等其他程式語言的任務。由於該工具的設計初衷不同,在大型專案中使用它會面臨挑戰,因為它缺乏 Tuist 所提供的彈性、效能與能力。Scaling iOS at Bumble 一文清楚說明了這一點,文中包含以下表格,比較了 Swift Package Manager 與原生 Xcode 專案的效能:

比較使用 SPM 相較於原生 Xcode 專案時的效能衰退表格

我們經常遇到開發者與組織質疑 Tuist 的必要性,認為 Swift Package Manager 也能擔任類似的專案管理角色。有些團隊嘗試遷移後,才發現開發體驗大幅退化。例如,重新命名一個檔案可能需要長達 15 秒才能完成重新索引。15 秒!

Apple 是否會讓 Swift Package Manager 成為專為大規模設計的專案管理工具,目前仍不確定。 然而,我們並未看到任何跡象顯示此事正在發生。事實上,我們看到的是相反的情況。他們做出受 Xcode 啟發的決策,例如透過隱式設定來達成便利性,而如你所知,這正是大規模下產生複雜性的根源。我們認為,Apple 需要回歸基本原則,重新檢視某些作為相依性管理工具合理、但作為專案管理工具並不合理的決策,例如使用編譯型語言作為定義專案的介面。

將 SPM 僅視為相依性管理工具

Tuist 將 Swift Package Manager 視為相依性管理工具,而且它在這方面表現出色。我們用它來解析並建置相依性。我們不會用它來定義專案,因為它並非為此設計。

從 Swift Package Manager 遷移至 Tuist#

Swift Package Manager 與 Tuist 之間的相似性讓遷移過程變得直截了當。主要差異在於,你將使用 Tuist 的 DSL 來定義專案,而非 Package.swift。

首先,在 Package.swift 旁邊建立 Project.swift 檔案。Project.swift 檔案將包含你的專案定義。以下是一個 Project.swift 檔案的範例,定義了一個具有單一目標的專案:

swift
import ProjectDescription
let project = Project(
name: "App",
targets: [
.target(
name: "App",
destinations: .iOS,
product: .app,
bundleId: "dev.tuist.App",
sources: ["Sources/**/*.swift"]*
),
]
)

注意事項:

  • ProjectDescription:你將使用 ProjectDescription,而非 PackageDescription。
  • Project: 你將匯出 project 實體,而非 package 實體。
  • Xcode 語言: 你用來定義專案的基本要素模仿了 Xcode 的語言,因此你會找到 Scheme、目標與建置階段等項目。

接著建立具有以下內容的 Tuist.swift 檔案:

swift
import ProjectDescription
let tuist = Tuist()

Tuist.swift 包含你的專案設定,其路徑可作為判斷專案根目錄的參考。你可以查看目錄結構文件,進一步了解 Tuist 專案的結構。

編輯專案#

你可以使用tuist edit在 Xcode 中編輯專案。此命令會產生一個 Xcode 專案,讓你開啟並開始工作。

bash
tuist edit

視專案規模而定,你可以考慮一次性或逐步採用。我們建議從小型專案開始,以熟悉 DSL 與工作流程。我們的建議始終是從被依賴最多的目標開始,逐步向上推進至最上層目標。