當模組化專案後,專案會切分成一個 app 專案或一個 framework 專案,和數個 Swift packages。我們可以用 Xcode workspaces 輕鬆地管理這些子專案。本文章將介紹如何使用 Xcode workspaces 來管理數個子專案。
Table of Contents
建立 Xcode Workspace
點選 File -> New -> Workspace 來建立一個 workspace。
輸入 Greeting 作為 workspace 的名稱。建立一個資料夾叫 iOSWorkspaceExample,並將 Greeting workspace 建立在這個資料夾之下。
Greeting workspace 建立好了。不過目前它沒有包含任何專案。
在 Workspace 中建立 Swift Package
現在我們要在 Greeting workspace 中,建立一個 Swift package。點選 File -> New -> Package。
輸入 GreetingPhrases 作為 Swift package 的名稱,並選擇要建立在 iOSWorkspaceExample 資料夾下。在視窗下方的 Add to 和 Group 欄位,我們選擇將 GreetingPhrases 加入到 Greeting workspace,並且加入到 Greeting group。
現在 Greeting workspace 包含一個 Swift package。
在 Workspace 中建立 Framework 專案
接下來我們要在 Greeting workspace 中,建立一個 framework。點選 File -> New -> Project。
選擇建立 Framework 專案。
輸入 GreetingUI 作為 framework 的名稱。
選擇要將 GreetingUI 建立在 iOSWorkspaceExample 資料夾下。在視窗下方的 Add to 和 Group 欄位,我們選擇將 GreetingUI 加入到 Greeting workspace,並且加入到 Greeting group。
現在 Greeting workspace 包含一個 Swift package 和一個 framework。
在 Workspace 中建立 App 專案
最後我們要在 Greeting workspace 中,建立一個 App。點選 File -> New -> Project。
選擇建立 App 專案。
輸入 GreetingApp 作為 App 的名稱。
選擇要將 GreetingApp 建立在 iOSWorkspaceExample 資料夾下。在視窗下方的 Add to 和 Group 欄位,我們選擇將 GreetingApp 加入到 Greeting workspace,並且加入到 Greeting group。
現在 Greeting workspace 包含一個 app、一個 framework、和一個 Swift package。
加入 Swift Package 依賴到 Framework
GreetingUI 和 GreetingPhrases 都在 Greeting workspace 裡面。所以 GreetingUI 不需要在加入 GreetingPhrases 依賴。Xcode workspace 會自動幫我們處理 workspace 中所有專案的依賴關係。但是 GreetingUI 還無法使用 GreetingPhrases。它還必須要將 GreetingPhrases 加入到它的 Frameworks and Libraries 列表。而這個步驟必須要由我們做,Xcode 不會幫我們處理。
選擇 GreetingUI 的 TARGETS 下的 GreetingUI target,點選在 Frameworks and Libraries 下方的 + 按鈕。
選擇加入 GreetingPhrases library。
在將 GreetingPhrases library 加入到 GreetingUI 的 Frameworks and Libraries 列表後,GreetingUI 就可以使用 GreetingPhrases 了。
以下程式碼顯示,如何在 GreetingUI 中使用 GreetingPhrase。
import UIKit import GreetingPhrases public class GreetingViewController: UIViewController { public static func newInstance() -> GreetingViewController { let storyboard = UIStoryboard(name: "Greeting", bundle: Bundle(for: Self.self)) let viewController = storyboard.instantiateViewController(withIdentifier: "GreetingViewController") as! GreetingViewController return viewController } @IBOutlet weak var greetingLabel: UILabel! public override func viewDidLoad() { super.viewDidLoad() greetingLabel.text = GreetingPhrases().text } }
加入 Swift Package 和 Framework 依賴到 App
GreetingApp 不需要在加入 GreetingPhrases 依賴,因為 Xcode workspace 會自動幫我們處理。但 GreetingApp 還必須要將 GreetingPhrases 和 GreetingUI 加入到它的 Frameworks and Libraries 列表。
選擇 GreetingApp 的 TARGETS 下的 GreetingApp target,點選在 Frameworks and Libraries 下方的 + 按鈕。
選擇加入 GreetingPhrases library。
再次點選 + 按鈕,並選擇加入 GreetingUI framework。
在將 GreetingPhrases library 和 GreetingUI framework 加入到 GreetingApp 的 Frameworks and Libraries 列表後,GreetingApp 就可以使用它們了。
以下程式碼顯示,如何在 GreetingApp 中使用 GreetingPhrase 和 GreetingUI。
import UIKit import GreetingUI import GreetingPhrases class ViewController: UIViewController { @IBOutlet weak var showButton: UIButton! @IBAction func onClick(_ sender: Any) { let viewController = GreetingViewController.newInstance() present(viewController, animated: true) } override func viewDidLoad() { super.viewDidLoad() showButton.setTitle("Show \(GreetingPhrases().text)", for: .normal) } }
執行 App
因為 Greeting workspace 有三個 schemes,記得要選 GreetingApp 來執行。即使我們在 GreetingUI 或 GreetingPhrases 中修改程式碼,我們可以直接執行 GreetingApp。而不需要先切換到 GreetingUI 或 GreetingPhrases 來編譯後,在切換回 GreetingApp 執行。當我們執行 GreetingApp 時,Xcode 會自動幫我們重新編譯 GreetingUI 和 GreetingPhrases。是不是非常地方便呢!
結語
Swift packages 允許我們模組化專案,將它切分成數個 Swift packages。或是當我們在開發 framework 時,我們會需要一個 app 來測試。也就是說,我們的專案有數個子專案時,Xcode workspace 可以幫我有效地管理它們之間的依賴關係。