MVVM Data Binding Using Observable (Box) Pattern
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取得資料,過程包括:
- 向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)
- Delegate Pattern
- Function Reactive Programing:第三方Library有,RxSwift、ReactiveCocoa,Apple官方有Combine
- 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指定方式去通知。
- 新增一個儲存不同觀眾的訂閱變數
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) } } }}
完整原始碼
使用方式
- 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()}
完整程式碼






