Skip to content

Conversation

@stephencelis
Copy link
Member

@stephencelis stephencelis commented Nov 14, 2025

Currently, the @FetchAll, @FetchOne, and @Fetch property wrappers work the same way that SwiftData's @Query property wrapper work: they observe and cause view updates as long as they are in the view hierarchy, regardless of if the view is visible or not. That means a list view powered by a @FetchAll will continue to recompute even if you're drilled down into a detail screen.

To work around this, you must explicitly stop observation, using events like onDisappear:

.task {
  try? await $reminders.load(Reminder.order(by: \.isCompleted))
}
.onDisappear {
  Task { try await $reminders.load(Reminder.none) }
}

This PR introduces a new FetchTask type that is returned from load, which you can optionally await to tie the cancellation of the current Swift task to the database observation. To migrate to it from the above workaround:

 .task {
-  try? await $reminders.load(Reminder.order(by: \.isCompleted))
+  try? await $reminders.load(Reminder.order(by: \.isCompleted)).task
 }
-.onDisappear {
-  Task { try await $reminders.load(Reminder.none) }
-}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants