See the following View and the supporting model. The view is not updating with the search results generated through the .task beerViewVM.search call.
The search is working fine as the print statements (see below) after the await each print the correct information. However, the view is not updated with these values.
I’m still learning managing state so I imagine I’m overlooking the obvious. I would appreciate any guidance. Thanks — jay
//
// BeerView.swift
//
import SwiftUI
struct BeerView: View {
@StateObject private var beerViewVM = BeerDetailViewModel()
let bid: Int
var body: some View {
VStack {
VStack (alignment: .leading) {
Text(beerViewVM.response?.beer.beerName ?? "no name")
.font(.largeTitle)
.fontWeight(.bold)
Text(beerViewVM.response?.beer.brewery.breweryName ?? "no brewery")
.padding(.bottom)
.foregroundColor(.secondary)
HStack {
InfoCellView(text: String(format: "%.1f", beerViewVM.response?.beer.ratingScore ?? 0), label: "rating")
InfoCellView(text: String(format: "%.1f", beerViewVM.response?.beer.beerAbv ?? 0), label: "abv")
InfoCellView(text: String(format: "%.1f", beerViewVM.response?.beer.beerIbu ?? 0), label: "ibu")
}
.padding(.bottom)
Text(beerViewVM.response?.beer.beerDescription ?? "no rating")
}
.padding()
Spacer()
}
.task {
await beerViewVM.search(bid: bid)
print(beerViewVM.response!)
print("-----------")
print(beerViewVM.response!.beer.bid)
print(beerViewVM.response!.beer.beerName)
print("\(beerViewVM.response!.beer.ratingScore)")
}
}
}
struct InfoCellView: View {
let text: String
let label: String
var body: some View {
VStack(alignment: .leading) {
Text(text)
.font(.title2)
.fontWeight(.bold)
Text(label)
.font(.caption)
.foregroundColor(.secondary)
}
.frame(width: 50.0)
}
}
//
// BeerDetailViewModel.swift
//
import Foundation
@MainActor
class BeerDetailViewModel: ObservableObject {
@Published var response: ResponseBeer?
func search(bid: Int) async {
do {
let response = try await Webservice().getBeerInfo(bid: bid)
self.response = response
} catch {
print(error)
}
}
}
struct BeerViewModel {
let beer: Beer
var bid: Int {
beer.bid
}
var beerName: String {
beer.beerName
}
var beerLabel: String {
beer.beerLabel
}
var beerAbv: Double {
beer.beerAbv
}
var beerIbu: Int {
beer.beerIbu
}
var beerDescription: String {
beer.beerDescription
}
}