Using ViewModel with Protocols in SwiftUI
Start by defining the view model protocol that outlines the properties and methods that your views will interact with.
This protocol serves as the contract that your view models will conform to.
import Foundation
protocol CounterViewModelProtocol {
var count: Int { get set }
func didTapIncrement()
func didTapDecrement()
}
Implement a concrete class that conforms to the view model protocol.
This class will provide the actual functionality and data that your views will use.
import Foundation
@Observable
final class CounterViewModelImpl: CounterViewModelProtocol {
var count: Int = 0
func didTapIncrement() {
count += 1
}
func didTapDecrement() {
count -= 1
}
}
Inject the view model into the view using the @State property wrapper.
import SwiftUI
struct CounterView<ViewModel>: View where ViewModel: CounterViewModelProtocol {
@State private var viewModel: ViewModel
init(viewModel: ViewModel) {
self._viewModel = State(wrappedValue: viewModel)
}
var body: some View {
VStack {
Text("\(viewModel.count)")
Button("Increment") {
viewModel.didTapIncrement()
}
Button("Decrement") {
viewModel.didTapDecrement()
}
}
}
}
let viewModel = CounterViewModelImpl()
CounterView(viewModel: viewModel)