For a personal project, I am trying to set up an app according MVVM with Aviation Weather Data. I have a SearchBarView with a connected SearchBarViewModel. In this SearchBarViewModel, there is only one @Published var which is the Airport code (Two-way binded with the SearchBarView). I want to share this property with a class to make a network request. It seems that there is something wrong between the SearchBarView and the SearchBarViewModel, but I cannot find the problem...
import SwiftUI
struct SearchBarView: View {
@ObservedObject var viewModel = SearchBarViewModel()
var body: some View {
HStack {
Button {
//Locate nearest airport with CoreLocation.
} label: {
Image(systemName: "location.circle")
.resizable()
.frame(width: 30, height: 30)
.foregroundColor(.primary)
}
TextField("Enter ICAO Code", text: $viewModel.airportCode)
.padding(.horizontal)
.padding(.vertical, 8)
.background(Color.gray.opacity(0.2))
.cornerRadius(10)
}
}
}
------------------------------------
import Foundation
import SwiftUI
final class SearchBarViewModel: ObservableObject {
@Published var airportCode = ""
}
When I type something in the TextField in the ContentView, The SearchBarViewModel is not "updated" and does not publish anything...`
SwiftUI is already MVVM you don't need your own objects, that is what
@State
is for. So it's just:SwiftUI will take your hierarchy of
View
data structs, diff it, then use the difference in the data to generate theV
layer automatically for you choosing the best UIKit, AppKit etc. objects depending on the platform/context.When passing data down to child Views - pass down
let
for read access or@Binding var
for read/write. In both casesbody
is called when the values change, think ofbody
like an "onChange". The result is then diffed.You can put your funcs for logic anywhere you like and make them return values you set on
@State
. Or you can group vars together into a custom struct and add a mutating func there. But since this is Swift just try to avoid classes when you can or you'll run into consistency issues/memory leaks since its tricky to get right, as you experienced.