How do you observe the count of records in a Swift Data relationship?

What is the correct way to track the number of items in a relationship using SwiftData and SwiftUI?

Imagine a macOS application with a sidebar that lists Folders and Tags. An Item can belong to a Folder and have many Tags. In the sidebar, I want to show the name of the Folder or Tag along with the number of Items in it.

I feel like I'm missing something obvious within SwiftData to wire this up such that my SwiftUI views correctly updated whenever the underlying modelContext is updated.

// The basic schema 

@Model final class Item { 
  var name = "Untitled Item"
  var folder: Folder? = nil
  var tags: [Tag] = []
}

@Model final class Folder { 
  var name = "Untitled Folder"
  var items: [Item] = []
}

@Model final class Tag { 
  var name = "Untitled Tag"
  var items: [Item] = []
}

// A SwiftUI view to show a Folder.

struct FolderRowView: View { 

  let folder: Folder 
 
  // Should I use an @Query here??
  // @Query var items: [Item]

  var body: some View { 
    HStack { 
      Text(folder.name)
      Spacer()
      Text(folder.items.count.formatted())
    }
  }
}

The above code works, once, but if I then add a new Item to that Folder, then this SwiftUI view does not update. I can make it work if I use an @Query with an #Predicate but even then I'm not quite sure how the #Predicate is supposed to be written. (And it seems excessive to have an @Query on every single row, given how many there could be.)

struct FolderView: View { 


  @Query private var items: [Item]
  private var folder: Folder

  init(folder: Folder) { 
    self.folder = folder
    
    // I've read online that this needs to be captured outside the Predicate?
    let identifier = folder.persistentModelID
    
    _items = Query(filter: #Predicate { link in 
      // Is this syntax correct? The results seem inconsistent in my app...

      if let folder = link.folder { 
       return folder.persistentModelID == identifier
      } else { 
        return false
      }
    })
  }

  var body: some View { 
    HStack { 
      Text(folder.name)
      Spacer()
      // This mostly works.
      Text(links.count.formatted())
    }
  }
}

As I try to integrate SwiftData and SwiftUI into a traditional macOS app with a sidebar, content view and inspector I'm finding it challenging to understand how to wire everything up.

In this particular example, tracking the count, is there a "correct" way to handle this?

There are some subtle things that determine if a change on a SwiftData model is observable, as discussed in this WWDC25 session (starting from around 14:00.)

Your code snippet doesn't show where the folder in FolderView is from and how you add a new item. If you can share a runnable code snippet that demonstrates the issue, I'd be able to figure out why folder doesn't trigger an update.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

How do you observe the count of records in a Swift Data relationship?
 
 
Q