Change tracking for transient SwiftData properties in SwiftUI

367 views Asked by At

How can I recognize a state change for a SwiftData @Transient property in SwiftUI? The change tracking works as expected for persistent and computed properties, but not for transient properties.

Sample code:

@Model
final class Item {
    var timestamp: Date
    var isProcessing = false
    
    init(timestamp: Date) {
        self.timestamp = timestamp
    }
    
    @MainActor
    func processSomething() async {
        isProcessing = true
        await someAsyncMethod()
        isProcessing = false
    }
    
    func someAsyncMethod() async {
        return await withCheckedContinuation { continuation in
            DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .seconds(2)) {
                continuation.resume()
            }
        }
    }
}

struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var items: [Item]
    
    var body: some View {
        VStack {
            List {
                ForEach(items) { item in
                    HStack {
                        Button {
                            Task {
                                await item.processSomething()
                            }
                        } label: {
                            Text(item.timestamp, style: .time)
                        }
                        if item.isProcessing {
                            Text("is processing")
                        } else {
                            Text("is not processing")
                        }
                    }
                }
            }
            Button("Add Item", action: addItem)
        }
    }
    
    private func addItem() {
        let newItem = Item(timestamp: Date())
        modelContext.insert(newItem)
    }
}

This sample code works, since isProcessing is persistent property. However, if i change

var isProcessing = false

to

@Transient
var isProcessing = false

the SwiftUI view does not update.

0

There are 0 answers