我想大多數iOS第一個開發的Design Pattern都是MVC
畢竟蘋果官方都那麼推薦你去使用這個框架
簡單說一下 我對這個架構的淺薄理解:
架構分工清楚
如果遇到大型專案,很容易造成massive VC
架構分工更細節,更容易找到出錯的Bug位置
寫起來很複雜,會多上很多行的程式碼
MVVM在名詞解釋實際上是指
Model、ViewController、ViewModel
這三個主要的分類
Model: 負責定義資料型態,像是從遠端抓取資料下來,需要使用哪個資料結構來儲存,就會把它放在Model層去處理
ViewController: 負責"UI"邏輯轉跳,像是跳下一頁、跳出Alert提醒、返回上一頁都會在這層進行處理
ViewModel: 負責進行"資料"邏輯處理,像是點選確認按鈕檢查目前所有欄位是否都有填上資料....
然而這次我要使用的是MVVM架構來進行實作會分為上下兩篇來寫
這次要講的是MVVM中的Model、ViewModel部分
舉例我這次要使用的打的API回傳的JSON檔案是一個 包含電影名稱、照片URL的Array
{
[
{
title: "天外奇蹟"
image: "https://i.imgur.com/LwExiFq.png"
},
{
title: "神隱少女"
image: "https://i.imgur.com/LxYy9GD.png"
}
]
}
那麼我的Model層就會這樣去寫,Model負責放打完API回來要儲存的資料結構
struct ExampleModel: Codable {
let movieArr: [Movie]
}
/// 負責接收來自API的資料
struct Movie: Codable {
let title: String
let image: String
}
ViewModel是在MVVM當中負責進行資料處理的一個Class
我會在創立ViewModel的class之前先建立protocol來作為進行binding的媒介
// 進行inputs綁定的Protocol
protocol ExampleViewModelInputs {
// 裡面會是ViewModel內所以需要被VC中呼叫的Function
// 舉例:如果要使用到API資料,都會需要downloadData這一個步驟
func downloadData()
}
// 進行outputs綁定的Protocol
protocol ExampleViewModelOutputs {
// 這邊會是在VC中被binding的Variable參數,Variable參數為Closure,就能夠定義在VC中的動作
// 舉例:像是剛剛Get到新的Data之後,第一個動作就是去reload一次Data
var reloadData:(() -> Void)? { get set }
}
Class ExampleViewModel: ExampleViewModelInputs, ExampleViewModelOutputs {
// 這是因為要讓VC更好的分區分這個Function是來inputsProtocol所定義的,而非ViewModel本身的func
// 通常都會需要定義好inputsProtocol內就是ViewModel中所有會使用到的Func,這算是過一層防呆
var intpus: ExampleViewModelIntputs { return self }
var outputs: ExampleViewModelOutputs { return self }
// 因為ViewModel這個Class遵守這個兩個Protocol,那麼這兩個Protocol的所定義的東西都必須要遵守
// outputs
var relaodData: (() -> Void)? // 實際實作會在VC,下篇會說
// inputs
func downloadData() {
// 打API
// 打上API後,進行reloadData(更新VC)
reloadData?()
}
}
我覺得最會遇到的問題會是MVC轉換到MVVM的不適應
因為我之前都寫MVC寫得很習慣了,現在換成MVVM,所有處理完後要更新的部分,都會先透過ViewModel再跑到VC,而非直接在VC中,需要轉換適應。