The Problem:
In a SwiftUI application using SwiftData, a list displays a count of comments associated with each post. When a new comment is added to a post from a different view, the comment count in the list doesn’t update until the app is relaunched. The goal is to find a solution to automatically update the comment count in the list view when a new comment is added, without requiring the app to be relaunched.
The Solutions:
Solution 1: Remove the subview PostListItem
This solution involves removing the subview PostListItem
and rendering each Post
directly in the List
. This eliminates the need for passing the single Post
to PostListItem
, thereby resolving the issue.
struct PostsList: View {
@Query var posts: [Post]
var body: some View {
List {
ForEach(posts) { post in
Text("\(post.title)")
Text("\(post.comments?.count ?? 0) comments")
}
}
}
}
In this approach, the Post
instances are directly rendered in the List
, which simplifies the view structure and avoids the potential issue caused by passing the Post
to a subview.
Solution 2: Wrap the Post
in a view model annotated with @Observable
This solution involves wrapping the Post
in a view model annotated with @Observable
and using it as state in PostListItem
. This allows SwiftUI to track changes to the view model and update the view accordingly.
struct PostsList: View {
@Query var posts: [Post]
var body: some View {
List {
ForEach(posts) { post in
PostListItem(model: post)
}
}
}
}
@Observable
class PostListItemModel {
var post: Post
init(post: Post) {
self.post = post
}
}
struct PostListItem: View {
var model: PostListItemModel
var body: some View {
Text("\(model.post.title)")
Text("\(model.post.comments?.count ?? 0) comments")
}
}
In this approach, the Post
instance is wrapped in the PostListItemModel
, which is annotated with @Observable
. This allows SwiftUI to observe changes to the PostListItemModel
and update the UI accordingly. When a comment is added or removed, the PostListItemModel
is updated, triggering a refresh of the view.
Q&A
Why SwiftData not refreshing given query?
The issue is in passing single Post
to PostListItem
.
What are the two solutions for the issue?
- Remove
PostListItem
subview, render eachPost
directly in the list. 2. WrapPost
inObservable
annotated view model used as state inPostListItem
.
Video Explanation:
The following video, titled "Let's explore and discover SwiftData (WWDC23) - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.
Let's explore and discover SwiftData (WWDC23). 4.2K views · Streamed 7 months ago ...more. Vincent Pradeilles. 14.2K. Subscribe.
The following video, titled "Let's explore and discover SwiftData (WWDC23) - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.
Let's explore and discover SwiftData (WWDC23). 4.2K views · Streamed 7 months ago ...more. Vincent Pradeilles. 14.2K. Subscribe.