How to implement MVVM pattern using SwiftUI and Combine
1. ContentView.swift
import SwiftUI
struct ContentView: View {
//You have to declare viewModel as @ObservedObject, so you can bind viewModel's property
//to SwiftUI's view
@ObservedObject private var viewModel: ViewModel
init(viewModel: ViewModel) {
self.viewModel = viewModel
}
var body: some View {
VStack {
Text(String(viewModel.count))
Spacer().frame(height: 10)
Button(action: {
viewModel.plus()
}, label: {
Text("Plus")
})
Spacer().frame(height: 10)
Button(action: {
viewModel.minus()
}, label: {
Text("Minus")
})
Spacer().frame(height: 20)
Text(viewModel.inputText)
Spacer().frame(height: 10)
Text(viewModel.descriptionText)
Spacer().frame(height: 10)
//Using $, you can store user's inputText in viewModel's property
TextField("텍스트를 입력하세요", text: $viewModel.inputText)
.frame(alignment: .center)
.multilineTextAlignment(.center)
.keyboardType(.default)
}
.padding()
}
}
#Preview {
ContentView(viewModel : ViewModel())
}
2. ViewModel.swift
import Foundation
import Combine
//ViewModel have to inherit ObservableObject for MVVM pattern
class ViewModel: ObservableObject {
init() {
print("ViewModel init")
//Subscribe descriptionPublisher and assign value to descriptionText property
descriptionPublisher
.receive(on: RunLoop.main)
.assign(to: \.descriptionText, on: self)
.store(in: &cancellableBag)
}
//You can publish data and subscribe data using @Published
@Published var count: Int = 0
@Published var inputText: String = ""
@Published var descriptionText: String = ""
//Subscribe inputText data and transform data using map method
var descriptionPublisher : AnyPublisher<String, Never> {
return $inputText
.map { "현재 텍스트의 길이는 " + String($0.count) + "입니다." }
.eraseToAnyPublisher()
}
private var cancellableBag = Set<AnyCancellable>()
func plus() {
print("viewModel plus called")
count += 1
}
func minus() {
print("viewModel minus called")
count -= 1
}
deinit {
cancellableBag.removeAll()
}
}
The full code is in below url:
https://github.com/antwhale/SampleCombineCounter
댓글 없음:
댓글 쓰기