ios – Why doesn’t onChange(of: @Question outcomes) fireplace when a SwiftData mannequin’s property adjustments?

0
1
ios – Why doesn’t onChange(of: @Question outcomes) fireplace when a SwiftData mannequin’s property adjustments?


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!

LEAVE A REPLY

Please enter your comment!
Please enter your name here