付費限定

✨Swift Dependencies 的語法靈感來自 SwiftUI Environment

13-avatar-img
發佈於📦 推薦 Swift Package 個房間
更新 發佈閱讀 13 分鐘

這篇文章是推坑 Swift Dependencies 系列的第四篇。前面三篇談到了這個套件解決的問題,並以 Date 與 UUID 為範例。

接下來,我要先介紹 dependency client 的語法是怎麼來的。

以 Swift Dependencies 內建的 Date 工具為例,用法是:@Dependency(\.date.now) var now

如果你熟悉 SwiftUI,可能會覺得有點微妙。那是因為,Swift Dependencies 的語法靈感正是來自 SwiftUI。更精確的說,是 Environment 機制。

簡介 SwiftUI Environment

在 SwiftUI 當中,Environment 是「從上層往下層傳遞」的資訊,相對於 Preferences 是由下往上傳遞。

你可以在任何 SwiftUI View 加上 .environment(\.key, value),指定 value 來覆蓋這個 View 以下所有讀取 @Environment(\.key) var value 的地方。

SwiftUI 預設提供了許多 Environment Key。你只要輸入 @Environment(\. 就可以從自動完成列表看到各種 keys。

自動出現的 Environment Keys

自動出現的 Environment Keys

除了這些內建的 Environment Key,SwiftUI 也提供了自訂的方式。

最初的語法是使用 EnvironmentKey,並且用 computed var 的方式延伸 EnvironmentValues。後續 Apple 提供了簡化的語法,我放在文章最後作為補充。

完整實作一個自訂 Environment 的方式如下,摘自官方文件

// 1. Create a custom EnvironmentKey
private struct MyEnvironmentKey: EnvironmentKey {
static let defaultValue: String = "Default value"
}

// 2. Extend EnvironmentValues with computed var
extension EnvironmentValues {
var myCustomValue: String {
get { self[MyEnvironmentKey.self] }
set { self[MyEnvironmentKey.self] = newValue }
}
}

// 3. Override a value on a SwiftUI view
MyView()
.environment(\.myCustomValue, "Another string")


// 4. Read the value in a SwiftUI view
@Environment(\.myCustomValue) var customValue: String

在 Swift Dependencies 宣告自訂的 dependency client

看完了 SwiftUI Environment 的宣告與使用語法,接下來我們回頭看 Swift Dependencies。

這篇文章暫時不解釋 Swift Dependencies 的語法與實作細節,之後會討論。目前請先把焦點放在語法的觀察上。

在宣告自訂的 dependency client 時,通常會有以下結構:

  1. 以 Sendable struct 為基礎型別
  2. 每一個方法都是以 @Sendable closure 的方式提供
  3. 建議加上 @DependencyClient Macros 來自動產生部分 closure 的預設值,簡化語法。需要import DependenciesMacros
import Dependencies
import DependenciesMacros

// 1. Create a dependency client
@DependencyClient
public struct APIClient: Sendable {
public var fetchNumber: @Sendable () async throws -> Int
}

之所以加上 public,是因為通常 dependency client 的宣告與使用,會在不同的模組。至於為何使用 struct 與 closures,以及 @DependencyClient Macros 做了哪些事情,會在之後的文章進行討論。

接著,我們要讓這個型別遵循 TestDependencyKey,並且實作 testValue

// 2. Conform to TestDependencyKey protocol
extension APIClient: TestDependencyKey {
public static let testValue = Self()
}

最後,延伸 DependencyValues,讓它可以被 @Dependency 找到。

// 3. Extend DependencyValues with computed var
extension DependencyValues {
public var apiClient: APIClient {
get { self[APIClient.self] }
set { self[APIClient.self] = newValue }
}
}

// 4. Usage
@Dependency(\.apiClient) var apiClient
let number = try await apiClient.fetchNumber()

比較 Swift Dependencies 與 SwiftUI Environment 語法

假如我們把 SwiftUI EnvironmentKey 拆成兩個步驟來寫,就可以看到 Swift Dependencies 跟它幾乎一模一樣 :

以行動支持創作者!付費即可解鎖
本篇內容共 5031 字、0 則留言,僅發佈於✍️ 學習 SwiftUI、📦 推薦 Swift Package你目前無法檢視以下內容,可能因為尚未登入,或沒有該房間的查看權限。
留言
avatar-img
留言分享你的想法!
avatar-img
13+
2.0K會員
122內容數
13 以 10+ 年 iOS 開發經驗為基礎撰寫,助你在 AI 時代成為更有自信的技術工作者。 ❤️ 支持 13 創作! 🤖 AI 工具實戰經驗與深度思考 🧠 軟體開發思維、職涯發展建議 💡 實用技巧與踩坑經驗分享 😔 開發者身心健康與職業傷害
13+的其他內容
2025/09/14
我過去對於推廣使用 Point-Free 的許多套件有所保留,因為使用 Swift Macros 來簡化語法,連帶依賴的 SwiftSyntax 會浪費大量的編譯時間。我甚至為了這個問題而換電腦。幸好自從 Xcode 16.4 以後獲得解決了!
2025/09/14
我過去對於推廣使用 Point-Free 的許多套件有所保留,因為使用 Swift Macros 來簡化語法,連帶依賴的 SwiftSyntax 會浪費大量的編譯時間。我甚至為了這個問題而換電腦。幸好自從 Xcode 16.4 以後獲得解決了!
2025/09/09
UUID 的隨機性讓測試變得不可預測。透過 Swift Dependencies 的 UUIDGenerator,我們可以在測試時產生遞增的 UUID,確保排序邏輯正確。還會自動識別運作環境,不影響實際 app 運作。
2025/09/09
UUID 的隨機性讓測試變得不可預測。透過 Swift Dependencies 的 UUIDGenerator,我們可以在測試時產生遞增的 UUID,確保排序邏輯正確。還會自動識別運作環境,不影響實際 app 運作。
2025/09/08
透過 Swift Dependencies 最基本的功能,就做到讓原本無法掌握的系統時間,變得完全可控。讀完肯定讓你躍躍欲試!
Thumbnail
2025/09/08
透過 Swift Dependencies 最基本的功能,就做到讓原本無法掌握的系統時間,變得完全可控。讀完肯定讓你躍躍欲試!
Thumbnail
看更多
你可能也想看
Thumbnail
想開始學塔羅卻不知道要準備哪些工具?這篇整理塔羅新手必備好物清單,從塔羅牌、塔羅布到收納袋與香氛噴霧一次入手。趁蝦皮雙11優惠打造專屬占卜空間,還能加入蝦皮分潤計畫,用分享創造收入。
Thumbnail
想開始學塔羅卻不知道要準備哪些工具?這篇整理塔羅新手必備好物清單,從塔羅牌、塔羅布到收納袋與香氛噴霧一次入手。趁蝦皮雙11優惠打造專屬占卜空間,還能加入蝦皮分潤計畫,用分享創造收入。
Thumbnail
今天不只要分享蝦皮分潤計畫,也想分享最近到貨的魔法少年賈修扭蛋開箱,還有我的雙11購物清單,漫畫、文具、Switch2、後背包......雙11優惠真的超多,如果有什麼一直想買卻遲遲還沒下手的東西,最適合趁這個購物季趕緊下單!
Thumbnail
今天不只要分享蝦皮分潤計畫,也想分享最近到貨的魔法少年賈修扭蛋開箱,還有我的雙11購物清單,漫畫、文具、Switch2、後背包......雙11優惠真的超多,如果有什麼一直想買卻遲遲還沒下手的東西,最適合趁這個購物季趕緊下單!
Thumbnail
這篇文章探討瞭如何在iOS應用程式中客製化Alert,包括改變字體大小、內嵌連結以及讓Alert的高度隨著字數增長並提供scroll操作。同時使用SwiftUI進行客製化,並介紹瞭解決高度超出範圍後文字捲動與scrollView固定高度的方法。
Thumbnail
這篇文章探討瞭如何在iOS應用程式中客製化Alert,包括改變字體大小、內嵌連結以及讓Alert的高度隨著字數增長並提供scroll操作。同時使用SwiftUI進行客製化,並介紹瞭解決高度超出範圍後文字捲動與scrollView固定高度的方法。
Thumbnail
本文介紹瞭如何在SwiftUI中調整元件的對齊方式,包括置中、向左/向右/向上/向下對齊的方法。透過調整HStack、VStack以及frame的maxWidth、maxHeight和alignment屬性,可以達到想要的對齊效果。
Thumbnail
本文介紹瞭如何在SwiftUI中調整元件的對齊方式,包括置中、向左/向右/向上/向下對齊的方法。透過調整HStack、VStack以及frame的maxWidth、maxHeight和alignment屬性,可以達到想要的對齊效果。
Thumbnail
本文檔介紹了在Swift中使用套件的詳細方法,包括如何引用第三方套件和自定義模組,如何創建自定義套件,以及一些常見的Swift套件。這些套件可以幫助開發者快速添加功能到項目中,提高開發效率和程式碼品質。
Thumbnail
本文檔介紹了在Swift中使用套件的詳細方法,包括如何引用第三方套件和自定義模組,如何創建自定義套件,以及一些常見的Swift套件。這些套件可以幫助開發者快速添加功能到項目中,提高開發效率和程式碼品質。
Thumbnail
這個章節主要介紹了Swift程式語言中物件導向程式設計的基本概念,包括類別、建構子、公開、私有、受保護等等的概念。同時,也介紹了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射等進階特性。
Thumbnail
這個章節主要介紹了Swift程式語言中物件導向程式設計的基本概念,包括類別、建構子、公開、私有、受保護等等的概念。同時,也介紹了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射等進階特性。
Thumbnail
本章節介紹了如何建立並設置Swift項目以及如何選擇和設置Swift代碼編輯器。這包括在Xcode和命令行中建立Swift項目,選擇Xcode、Visual Studio Code或AppCode作為編輯器,以及如何使用SPM安裝插件。
Thumbnail
本章節介紹了如何建立並設置Swift項目以及如何選擇和設置Swift代碼編輯器。這包括在Xcode和命令行中建立Swift項目,選擇Xcode、Visual Studio Code或AppCode作為編輯器,以及如何使用SPM安裝插件。
Thumbnail
這份文件的目的是介紹Swift語言,包括它的特性、應用範疇,以及誰在使用它。它也提供了一些學習Swift的資源和工具,以及一些常見的Swift庫和框架。
Thumbnail
這份文件的目的是介紹Swift語言,包括它的特性、應用範疇,以及誰在使用它。它也提供了一些學習Swift的資源和工具,以及一些常見的Swift庫和框架。
Thumbnail
Part.1 搞定基本的 UI 開始開發 iOS App。 首先準備一台 Mac,然後安裝 Xcode,新增專案,系統即刻生成基本的專案結構。coding 的起點在檔案 ContentView.swift: import SwiftUI struct ContentView: View {  
Thumbnail
Part.1 搞定基本的 UI 開始開發 iOS App。 首先準備一台 Mac,然後安裝 Xcode,新增專案,系統即刻生成基本的專案結構。coding 的起點在檔案 ContentView.swift: import SwiftUI struct ContentView: View {  
Thumbnail
只是 Swift 以 language level 支援 Optional 確實比用 API level 支援的 Java 要簡潔和更具可讀性。Swift 作為一個全新的語言,從一開始的設計就將許多好的語言特性加入,確實讓人驚豔。
Thumbnail
只是 Swift 以 language level 支援 Optional 確實比用 API level 支援的 Java 要簡潔和更具可讀性。Swift 作為一個全新的語言,從一開始的設計就將許多好的語言特性加入,確實讓人驚豔。
Thumbnail
這篇文章介紹了 iOS 中常用的 Design Patterns,包括 MVC、MVVM、Singleton、Delegation、Observer 等。同時比較了 Delegate 和 Notification 的使用時機。參考資料中還有更多相關資訊。
Thumbnail
這篇文章介紹了 iOS 中常用的 Design Patterns,包括 MVC、MVVM、Singleton、Delegation、Observer 等。同時比較了 Delegate 和 Notification 的使用時機。參考資料中還有更多相關資訊。
Thumbnail
在寫SwiftUI view的時候,碰到一個瓶頸(? 帶有Binding的參數要如何preview。 舉例來說有個右邊圖片左邊文字的View,給他一個@Binding var isActive: Bool的狀態,當active時圖片要跟著改變: struct RightImageView: Vie
Thumbnail
在寫SwiftUI view的時候,碰到一個瓶頸(? 帶有Binding的參數要如何preview。 舉例來說有個右邊圖片左邊文字的View,給他一個@Binding var isActive: Bool的狀態,當active時圖片要跟著改變: struct RightImageView: Vie
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News