Hi,
I’m new to Swift and also to SwiftUI.
For a small application that I want to implement I’d like to stick with MVVM.
But async tasks in the model are giving me a headache.
I have created a very simplified example to explain it:
The View:
import SwiftUI
struct ContentView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
VStack {
Text("\(viewModel.model.numberToDisplay)")
Button(action: {self.viewModel.model.increase()}) {
Text("increase")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(viewModel: ViewModel())
}
}
}The ViewModel:
import Foundation
import SwiftUI
class ViewModel: ObservableObject {
@Published var model = Model()
}And the Model:
import Foundation
struct Model {
private(set) var numberToDisplay: Int = 0
mutating func increase() {
for _ in 0...2 {
self.numberToDisplay += 1
sleep(1)
}
}
}Having this the UI will show “0” at the start. Hitting “increase” gives a blocked UI for 3s (see for loop in the model) and afterwards it’ll show “3”.
What I would like to have is a non-blocked UI and that all updates of numberToDisplay are shown (0 -> 1 -> 2 -> 3 instead of 0 -> 3).
If I try to use a DispatchQueue like this in the model:
DispatchQueue.global().async {
self.numberToDisplay += 1
}it just gives me an „Escaping closure captures mutating 'self' parameter” error.
Using a class instead of a struct for the model allows me to use a DispatchQueue, but even worse the UI does not get updated at all. (The usage of DispatchQueue does not play any role in here.)
So what the appropriate approach to use SwiftUI with MVVM and async functions within the model?
Any help is appreciated.
Best regards
AlphaPapa