用 Xcode Workspace 管理 Apps, Frameworks, 和 Swift Packages

Photo by Carissa Gan on Unsplash
Photo by Carissa Gan on Unsplash
當模組化專案後,專案會切分成一個 app 專案或一個 framework 專案,和數個 Swift packages。我們可以用 Xcode workspaces 輕鬆地管理這些小專案。

當模組化專案後,專案會切分成一個 app 專案或一個 framework 專案,和數個 Swift packages。我們可以用 Xcode workspaces 輕鬆地管理這些子專案。本文章將介紹如何使用 Xcode workspaces 來管理數個子專案。

完整程式碼可以在 下載。

建立 Xcode Workspace

點選 File -> New -> Workspace 來建立一個 workspace。

File -> New -> Workspace
File -> New -> Workspace

輸入 Greeting 作為 workspace 的名稱。建立一個資料夾叫 iOSWorkspaceExample,並將 Greeting workspace 建立在這個資料夾之下。

Create Greeting workspace.
Create Greeting workspace.

Greeting workspace 建立好了。不過目前它沒有包含任何專案。

Created workspace contains no projects.
Created workspace contains no projects.

在 Workspace 中建立 Swift Package

現在我們要在 Greeting workspace 中,建立一個 Swift package。點選 File -> New -> Package。

File -> New -> Package.
File -> New -> Package.

輸入 GreetingPhrases 作為 Swift package 的名稱,並選擇要建立在 iOSWorkspaceExample 資料夾下。在視窗下方的 Add to 和 Group 欄位,我們選擇將 GreetingPhrases 加入到 Greeting workspace,並且加入到 Greeting group。

Create GreetingPhrases Swift package.
Create GreetingPhrases Swift package.

現在 Greeting workspace 包含一個 Swift package。

Workspace contains Greeting package.
Workspace contains Greeting package.

在 Workspace 中建立 Framework 專案

接下來我們要在 Greeting workspace 中,建立一個 framework。點選 File -> New -> Project。

File -> New -> Project.
File -> New -> Project.

選擇建立 Framework 專案。

Choose framework to create.
Choose framework to create.

輸入 GreetingUI 作為 framework 的名稱。

Enter GreetingUI as the name of the framework.
Enter GreetingUI as the name of the framework.

選擇要將 GreetingUI 建立在 iOSWorkspaceExample 資料夾下。在視窗下方的 Add to 和 Group 欄位,我們選擇將 GreetingUI 加入到 Greeting workspace,並且加入到 Greeting group。

Create GreetingUI framework.
Create GreetingUI framework.

現在 Greeting workspace 包含一個 Swift package 和一個 framework。

Greeting workspace contains GreetingPhrases package and GreetingUI framework.
Greeting workspace contains GreetingPhrases package and GreetingUI framework.

在 Workspace 中建立 App 專案

最後我們要在 Greeting workspace 中,建立一個 App。點選 File -> New -> Project。

File -> New -> Project.
File -> New -> Project.

選擇建立 App 專案。

Choose App to create.
Choose App to create.

輸入 GreetingApp 作為 App 的名稱。

Enter GreetingApp as the name of the app.
Enter GreetingApp as the name of the app.

選擇要將 GreetingApp 建立在 iOSWorkspaceExample 資料夾下。在視窗下方的 Add to 和 Group 欄位,我們選擇將 GreetingApp 加入到 Greeting workspace,並且加入到 Greeting group。

Create GreetingApp.
Create GreetingApp.

現在 Greeting workspace 包含一個 app、一個 framework、和一個 Swift package。

Greeting workspace contains GreetingPhrases, GreetingUI, and GreetingApp.
Greeting workspace contains GreetingPhrases, GreetingUI, and GreetingApp.

加入 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 下方的 + 按鈕。

GreetingUI -> TARGETS -> GreetingPhrases.
GreetingUI -> TARGETS -> GreetingPhrases.

選擇加入 GreetingPhrases library。

Choose GreetingPhrases library to add to GreetingUI.
Choose GreetingPhrases library to add to GreetingUI.

在將 GreetingPhrases library 加入到 GreetingUI 的 Frameworks and Libraries 列表後,GreetingUI 就可以使用 GreetingPhrases 了。

GreetingUI has GreetingPhrases in the Frameworks and libraries list.
GreetingUI has GreetingPhrases in the Frameworks and libraries list.

以下程式碼顯示,如何在 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 下方的 + 按鈕。

GreetingApp -> TARGETS -> GreetingApp.
GreetingApp -> TARGETS -> GreetingApp.

選擇加入 GreetingPhrases library。

Choose GreetingPhrases library to add to GreetingApp.
Choose GreetingPhrases library to add to GreetingApp.

再次點選 + 按鈕,並選擇加入 GreetingUI framework。

Choose GreetingUI framework to add to GreetingApp.
Choose GreetingUI framework to add to GreetingApp.

在將 GreetingPhrases library 和 GreetingUI framework 加入到 GreetingApp 的 Frameworks and Libraries 列表後,GreetingApp 就可以使用它們了。

GreetingApp has GreetingPhrases and GreetingUI in the Frameworks and libraries list.
GreetingApp has GreetingPhrases and GreetingUI in the Frameworks and libraries list.

以下程式碼顯示,如何在 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。是不是非常地方便呢!

Choose GreetingApp scheme to run.
Choose GreetingApp scheme to run.

結語

Swift packages 允許我們模組化專案,將它切分成數個 Swift packages。或是當我們在開發 framework 時,我們會需要一個 app 來測試。也就是說,我們的專案有數個子專案時,Xcode workspace 可以幫我有效地管理它們之間的依賴關係。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

You May Also Like
Photo by Alex Alvarez on Unsplash
Read More

Dispatch Queue 教學

GCD 提供有效率的並行處理,讓我們不需要直接管理多執行緒。它的 Dispatch Queues 可以循序地(serially)或是並行地(concurrently)執行任務。我們只需要將要並行的程式當作任務提交到 dispatch queues 就可以了。
Read More
Photo by Florinel Gorgan on Unsplash
Read More

如何製作一個 XCFramework

XCFramework 讓你可以將 iPhone、iPhone 模擬器等多的不同平台的二進位碼打包到一個可發佈的 .xcframework 檔。你只需要為你的 Framework 產生出一個 .xcframework 檔,就可以支援多種平台。
Read More
Photo by Fabian Gieske on Unsplash
Read More

SwiftUI @State & @Binding 教學

SwiftUI 推出了兩個 Property Wrapper – @State and @Binding。利用它們可以達到變數的 Two-way Binding 功能。也就是當變數的值改變時,它會重新被顯示。本章藉由製作一個 Custom View 來展示如何使用 @State 和 @Binding。
Read More
Photo by Svitlana on Unsplash
Read More

iOS:禁止螢幕截圖

基於一些理由,我們可能會想要禁止使用者對我們的 app 做螢幕截圖。然而,iOS 並沒有提供這樣的功能。所幸,我們可以利用 UITextField 來達到此效果。
Read More