[SwiftUI] 使用 Combine 進行實時數據訂閱與更新

SwiftUI 和 Combine 讓 iOS 應用開發中的異步數據處理變得非常簡單且高效。特別是結合 @Published 和 Combine 的訂閱功能,數據實時更新時,視圖可以自動刷新。本篇將透過 ProfileViewModel 示例,介紹如何在 SwiftUI 中利用 Combine 進行數據實時更新與高效管理。

代碼示例: ProfileViewModel


class ProfileViewModel: ObservableObject {
    @Published var currentUser: User?
    private var cancellables = Set<AnyCancellable>()

    init() {
        setupSubscribers()
    }

    private func setupSubscribers() {
        UserService.shared.$currentUser.sink { [weak self] user in
            self?.currentUser = user
        }.store(in: &cancellables)
    }
}

此代碼定義了一個 ProfileViewModel ,用於實時更新用戶資料數據並反映至 SwiftUI 視圖。透過 Combine 的數據訂閱以及 @Published 屬性,可以輕鬆設定與 SwiftUI 的狀態聯動。

代碼分析

1. class ProfileViewModel: ObservableObject

ProfileViewModel 遵循了 ObservableObject 協議。這使得 ViewModel 能夠為 SwiftUI 視圖提供數據,並在數據變更時讓視圖自動更新。

2. @Published var currentUser: User?

@Published 屬性包裝器會讓 currentUser 在更新時,通知 SwiftUI 偵測到變更並重新渲染視圖。這使得數據流的管理變得 響應式 ,當用戶資訊改變時,視圖能立即反映。

3. private var cancellables = Set<AnyCancellable>()

這是一個用來儲存訂閱取消對象 AnyCancellable 的集合。在 Swift 中,為了防止記憶體洩漏並按需取消訂閱,妥善管理 Cancellable 是非常重要的。

4. init() setupSubscribers()

init 方法會在 ProfileViewModel 對象建立時呼叫,並透過 setupSubscribers() 方法初始化 Combine 的訂閱設定。

5. UserService.shared.$currentUser.sink { [weak self] user in ... }

這是 Combine 的核心部分。它訂閱 (subscribe) 了 UserService 中宣告為 @Published currentUser ,一旦數據變更,閉包 (closure) 就會執行。使用 [weak self] 是為了防止循環參照 (retain cycle),以弱參照方式獲取 self ,有利於記憶體管理。

6. self?.currentUser = user

將數據流中傳遞的 user 對象賦值給 ViewModel 的 currentUser 。這導致 SwiftUI 視圖偵測到數據已變更 ,進而重新渲染視圖。

7. print("DEBUG: User in view model from combine is \(user)")

此程式碼用於除錯 (debug),輸出透過 Combine 傳遞的數據。這在確認實時數據流時非常實用。

8. .store(in: &cancellables)

訂閱完成後將其儲存於 cancellables 中,以達到 防止記憶體洩漏 及管理訂閱的目的。此方法確保當 Combine 訂閱不再需要時,能從記憶體中自動釋放。


為何需要這段代碼?

  1. 實時數據反映 :當應用內用戶資訊變更時,需要實時更新時非常有用。例如,用戶登入或登出時,視圖模型可自動更新該資訊。
  2. 記憶體管理 :為了在訂閱結束時有效管理記憶體,必須能夠取消訂閱。利用 Combine 的 AnyCancellable 可取消不必要的訂閱,防止記憶體洩漏。
  3. 響應式應用設計 :SwiftUI 的優勢之一在於數據與視圖之間的 響應式流 。使用 Combine,數據變更時視圖會自動調整,用戶體驗到的是自然且實時更新的 UI。

結論

利用 Combine,可以輕鬆地訂閱數據流,並在狀態實時變更時輕易更新視圖。這種結合 SwiftUI 的機制,是現代 iOS 應用開發中強大的工具。特別是 @Published 與 Combine 的訂閱模式,對於有效管理數據流以及兼顧記憶體管理的應用開發來說,是必不可少的。

參考資料

AD