The 1 to 1 relation models:
@Model
class Country {
var name: String
var population: Population?
init(name: String, population: Population? = nil) {
self.name = name
self.population = population
}
}
@Model
class Population {
var country: Country?
var count: Int
init(country: Country? = nil, count: Int) {
self.country = country
self.count = count
}
}
I don't know why not update the UI when click population label. But if I expand the CountryDetail it will works.
struct DemoView: View {
@Query var countries: [Country]
@Environment(\.modelContext) private var context
var body: some View {
NavigationStack {
List {
ForEach(countries) { country in
VStack(alignment: .leading) {
Text(country.name)
if let population = country.population {
// bug: not update
CountryDetail(population: population)
// like above but expanded, it is ok
Text("population: \(population.count)")
.onTapGesture {
Task.detached {
try await DemoData(modelContainer: DemoData.sharedContainer).changePopulation()
}
}
}
}
}
}.safeAreaInset(edge: .bottom) {
Button("Add") {
let country = Country(name: "US")
context.insert(country)
let population = Population(country: country, count: 0)
country.population = population
}
}
}
}
}
struct CountryDetail: View {
@Bindable var population: Population
var body: some View {
Text("population: \(population.count)")
.onTapGesture {
Task.detached {
try await DemoData(modelContainer: DemoData.sharedContainer).changePopulation()
}
}
}
}
@ModelActor
actor DemoData {
static let sharedContainer = try! ModelContainer(for: Country.self, configurations: .init(isStoredInMemoryOnly: true))
func changePopulation() throws {
let descriptor = FetchDescriptor<Population>()
let all = try modelContext.fetch(descriptor).first
if let population = try modelContext.fetch(descriptor).first {
population.count += 1
try modelContext.save()
print("population count", population.count)
} else {
fatalError("not found population")
}
}
}