Drawback Description
When utilizing SwiftUI’s @Question
with SwiftData fashions, I encountered confusion about reactivity triggering. In sure conditions, SwiftUI’s reactivity mechanism would not work as anticipated when the MessageData
array adjustments.
Information Mannequin Definition
@Mannequin
last class MessageData: Equatable {
@Attribute(.distinctive) public var identify: String
public var etag: String?
public static func == (lhs: MessageData, rhs: MessageData) -> Bool {
// If each have etag, examine etags
if let lhsEtag = lhs.etag, let rhsEtag = rhs.etag {
return lhsEtag == rhsEtag
}
return false
}
}
struct MessageForDisplay {
public textual content: String
}
SwiftUI View Code
struct ChannelChatView: View {
@Question non-public var messages: [MessageData]
@State non-public var displayMessages: [MessageForDisplay]
var physique: some View {
MessagesView(messages: displayMessages)
.onChange(of: messages, preliminary: true) { _, _ in
prepareDisplayMessages(messages: messages)
}
}
func prepareDisplayMessages(messages: [MessageData]) {
// rework [MessageData] to [MessageForDisplay]
displayMessages = messages.map { message in
MessageForDisplay(textual content: message.textual content)
}
}
}
Set off Situations Comparability
Situation | Code Sample | Triggers doSomething() ? |
Clarification |
---|---|---|---|
Array parts added | .onChange(of: messages) |
✅ Triggers | SwiftData detects array adjustments |
Array parts eliminated | .onChange(of: messages) |
✅ Triggers | SwiftData detects array adjustments |
Particular person message.etag adjustments | .onChange(of: messages) |
❌ No set off | SwiftData would not detect inside property adjustments |
Utilizing .process(id: messages) | .process(id: messages) |
❌ No set off | Similar challenge – would not detect inside property adjustments |
Mapping etag array (onChange) | .onChange(of: messages.map { $0.etag }) |
✅ Triggers | Explicitly displays etag adjustments |
Mapping etag array (process) | .process(id: messages.map { $0.etag }) |
✅ Triggers | Explicitly displays etag adjustments |
Query
Why doesn’t onChange(of: messages)
observe adjustments to properties of the objects returned by @Question
? Is that this a limitation of SwiftData’s change monitoring, or am I lacking a unique sample for reacting to inside property adjustments?
Atmosphere
- Xcode 16.3
- iOS 18.1
- Swift 6.1
- SwiftData / SwiftUI
Any rationalization is appreciated!