Sitemap

MVVM Data Binding Using Observable (Box) Pattern

4 min readJun 5, 2022

--

Press enter or click to view image in full size
Photo by Liam Welch on Unsplash

MVVM設計為了分擔MVC的Controller過多工作,像是Life Cycle、Steup View、Animation、API Call、Biz Logic、Data Conversion、Delegate、IBAction…等等的,所以將部份工作,像是API Call、Biz Logic、Data Conversion、Data Source分給ViewModel。

ViewModel透過呼叫API取得資料,過程包括:

Press enter or click to view image in full size
  1. 向API Server請求(request) ,request組成有:

API URL

Http Mether:Get / Post / Put / Delete…

Body:將Model編碼成query string / x-www-form-urlencoded / JSON / XML…

Authentication:Basic、Oauth2、API Key…

2. API Server回應(response),處理過程有

檢查是否有error

檢查http response status code是不是介於200…299之間

檢查data是不是nil

將data編碼成指定Model

3. View Model從Model取得View所需要資料並加以處理

4. 通知View資料已經取得

通知View資料已經取得常見方式 (Data Binding)

  1. Delegate Pattern
  2. Function Reactive Programing:第三方Library有,RxSwift、ReactiveCocoa,Apple官方有Combine
  3. Observable (Box) Pattern

本篇文章主要介紹如果透過Observable (Box) Patter通知View有新的資料,並取得資料,將畫面更新。

Get 陳仕偉’s stories in your inbox

Join Medium for free to get updates from this writer.

Observable Pattern 運作方式,打個比方,觀眾A去訂閱某個Youtube Channel,設定通知方式(APP推播、加到待看清單、Email…),當Youtuber更新影片,按照觀眾A指定方式去通知。

  1. 新增一個儲存不同觀眾的訂閱變數
var observers = [Observer]()

Observer設定新影片通知方式,觀眾取得新影片

2. 提供訂閱功能,指定新影片通知方式,把觀眾A加入Observers通知清單

func bind(_ observer: @escaping Observer){  observers.append(observer)}

3. Youtuber發佈新影片時,執行通知並傳送新影片

var value: ObservableType? {  didSet{    if let value = value {      observers.forEach { observer in        observer(self, value)      }    }  }}

完整原始碼

使用方式

  1. ViewModel Class 宣告Observable type的變數
var movies: Observable<[DiscoverData.Movie]> = Observable([])

2. ViewController初始化ViewModel

let movieViewModel = MovieViewModel()

3. 設定viewModel的value(movies)有更新時,要執行程式碼

movieViewModel.movies.bind { [weak self] observable, movies in  guard let self = self else { return }  self.tableView.reloadData()}

完整程式碼

--

--