How it works
FetchedResults is the read-only collection that delivers the objects of a Core Data fetch request to your SwiftUI view. You don't create it yourself; the @FetchRequest property wrapper produces a FetchedResults value and keeps it in sync with the managed object context, refetching whenever the underlying store changes so your view always reflects the current data. Reach for it whenever a view needs to display a live, ordered set of persisted model objects and re-render automatically as those objects are inserted, updated, or deleted.
Obtain the collection from @FetchRequest
A FetchedResults value is the projected value of an @FetchRequest declaration — you declare the request and SwiftUI hands you the populated, auto-updating collection. The example stands in for this with a plain
itemsarray, but in a Core Data view that property would be aFetchedResults<Item>driven by the request's entity, sort descriptors, and predicate.Treat it as a RandomAccessCollection
FetchedResults conforms to RandomAccessCollection, so it supports indexing,
count, slicing, and iteration just like an array — but its elements are your managed objects in the request's sorted order. Because it's a collection, it drops straight into the data-driven views you already use without any conversion.Drive a ForEach with it
The collection is meant to feed list content: pass it directly to a
ForEach, which walks each fetched object and builds a row. HereForEach(items, id: \.self)iterates the stand-in collection and renders aLabelper element; swappingitemsfor aFetchedResults<Item>makes eachnamean attribute read off a fetched object instead.Identify elements for stable diffing
ForEach needs a stable identity per element so SwiftUI can animate insertions and removals as the fetch updates. Managed objects are Identifiable via their object ID, so a real fetch can use
ForEach(results)directly; the example suppliesid: \.selfonly because itsStringelements aren't otherwise identifiable.Let it refresh the view automatically
Because @FetchRequest stores its FetchedResults as observed state, any change to the matching objects in the context invalidates the body and re-runs the fetch — the
Listand itsSection("Shopping List")redraw with no manual reload. You read the collection; SwiftUI owns keeping it current.
let items = ["Milk", "Bread", "Eggs", "Coffee"] with an @FetchRequest(sortDescriptors: []) for an Item entity, then add and delete items in the context to watch the List update on its own as the FetchedResults collection refetches.Example & preview
Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.
struct FetchedResultsDemo: View {
// In a real app this comes from @FetchRequest, whose value is a FetchedResults<Item>.
let items = ["Milk", "Bread", "Eggs", "Coffee"]
var body: some View {
List {
Section("Shopping List") {
ForEach(items, id: \.self) { name in
Label(name, systemImage: "cart")
}
}
}
.padding()
}
}