@FetchRequest in SwiftUI — was es ist, Core Data Abfrage und Mechanismus

Autor: IT Sectr Veröffentlicht: 2026-06-25 Lesezeit: 8 Min.

@FetchRequest in SwiftUI — ein Property Wrapper zum automatischen Abrufen von Daten aus Core Data mit reaktiver Aktualisierung der Benutzeroberfläche. Der Wrapper akzeptiert NSFetchRequest mit Filterprädikaten und Sortierungen, und das Ergebnis — ein Array von NSManagedObject — wird bei Änderungen im Core Data Kontext automatisch aktualisiert. Laut Apple Developer Documentation (2025) benötigt @FetchRequest managedObjectContext in der SwiftUI-Umgebung und unterstützt dynamische Prädikate, wodurch eine reaktive Verbindung zwischen Core Data und der Benutzeroberfläche hergestellt wird.

Wichtige Punkte

  • @FetchRequest — ein Property Wrapper für reaktives Core Data Abrufen in SwiftUI
  • Automatische Aktualisierung der UI beim Hinzufügen, Löschen oder Ändern von Datensätzen in Core Data
  • Prädikate und Sortierungen werden im Initialisierer oder über Property Wrapper Parameter festgelegt
  • managedObjectContext muss über @Environment in der View-Hierarchie verfügbar sein
  • Dynamische Prädikate ermöglichen das Ändern von Filterbedingungen zur Laufzeit

Was ist @FetchRequest in SwiftUI?

@FetchRequest ist ein SwiftUI Property Wrapper, der einen FetchRequest aus Core Data erstellt und verwaltet. Bei der Initialisierung akzeptiert der Wrapper einen Entity-Typ, ein Array von NSSortDescriptor für die Sortierung und ein optionales NSPredicate für die Filterung. Das Ergebnis wird als Array von Objekten des angegebenen NSManagedObject-Typs gespeichert und bei Änderungen in der Persistenzschicht automatisch aktualisiert.

Das Hauptmerkmal von @FetchRequest ist die Reaktivität. Wenn sich Daten in Core Data ändern (save, insert, delete, update), führt SwiftUI automatisch einen erneuten Abruf durch und zeichnet alle Views neu, die diesen Fetch Request verwenden. Der Entwickler muss nicht manuell refresh aufrufen, NSManagedObjectContextDidSaveNotification abonnieren oder Daten neu laden. SwiftUI verwaltet den gesamten Synchronisationszyklus.

Damit @FetchRequest funktioniert, muss ein NSManagedObjectContext in der SwiftUI-Umgebung über @Environment(\.managedObjectContext) verfügbar sein. Der Kontext wird normalerweise vom Anwendungsstamm übergeben, wo ein NSPersistentContainer erstellt wird. Das Standardmuster ist die Verwendung eines ViewModels oder einer App-Struct zur Konfiguration des Core Data Stacks und die Übergabe des Kontexts über den .environment()-Modifikator.

Sortierung und Prädikate von FetchRequest

@FetchRequest akzeptiert mehrere Parameter zur Konfiguration des Abrufs. SortDescriptors — ein Array von NSSortDescriptor, das die Reihenfolge der Datensätze bestimmt. Predicate — ein NSPredicate zur Filterung, zum Beispiel nur Aufgaben mit dem Status „erledigt“ abzurufen. Animation — Animation zur Aktualisierung der Liste bei Datenänderungen.

Core Data Prädikate verwenden ein Format von SQL-ähnlichen Ausdrücken: NSPredicate(format: „status == %@“, „completed“). Mehrere Bedingungen können mit AND, OR und NOT kombiniert werden. SortDescriptors definieren die Reihenfolge: NSSortDescriptor(keyPath: \Task.dueDate, ascending: true). Zum Sortieren nach mehreren Feldern wird ein Array von Deskriptoren übergeben — der erste wird als primärer angewendet, die restlichen als sekundäre.

swift
struct TaskListView: View {
    @Environment(\.managedObjectContext) var viewContext

    @FetchRequest(
        sortDescriptors: [
            NSSortDescriptor(keyPath: \.Task.dueDate, ascending: true),
            NSSortDescriptor(keyPath: \.Task.priority, ascending: false)
        ],
        predicate: NSPredicate(format: "isCompleted == NO"),
        animation: .default
    )
    var tasks: FetchedResults<Task>

    var body: some View {
        List(tasks) { task in
            Text(task.title ?? "")
        }
    }
}

Im Beispiel ruft @FetchRequest alle unerledigten Aufgaben ab (isCompleted == NO), sortiert zuerst nach Datum (aufsteigend), dann nach Priorität (absteigend). FetchedResults<Task> ist eine automatisch aktualisierte Sammlung, die sich für ForEach und List wie ein Array verhält. Die .default-Animation sorgt für ein sanftes Erscheinen/Verschwinden der Datensätze bei Änderungen.

@FetchRequest mit List und dynamischen Daten

@FetchRequest lässt sich perfekt mit List und ForEach zur Anzeige dynamischer Core Data Listen kombinieren. Das Abrufergebnis (FetchedResults) entspricht dem RandomAccessCollection-Protokoll, sodass es direkt in List und ForEach verwendet werden kann. Beim Hinzufügen, Löschen oder Ändern von Datensätzen wird die Liste automatisch mit Animation neu gezeichnet.

Zum Löschen von Datensätzen wird die Kontextmethode delete verwendet. Zum Hinzufügen von Datensätzen wird ein neues NSManagedObject erstellt und save aufgerufen. Alle Änderungen werden über viewContext durchgeführt, der zusammen mit @FetchRequest die Datenkonsistenz gewährleistet. Zum Bearbeiten wird @ObservedObject oder @Bindable für ein bestimmtes Core Data Objekt verwendet.

swift
struct TaskListWithActions: View {
    @Environment(\.managedObjectContext) var viewContext

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \.Task.createdAt,
                                               ascending: false)]
    )
    var tasks: FetchedResults<Task>

    var body: some View {
        List {
            ForEach(tasks) { task in
                HStack {
                    Text(task.title ?? "")
                    Spacer()
                    Image(systemName: task.isCompleted
                               ? "checkmark.circle.fill"
                               : "circle")
                }
                .onTapGesture { toggleTask(task) }
            }
            .onDelete(perform: deleteTasks)
        }
        .toolbar {
            Button(systemImage: "plus") { addTask() }
        }
    }

    private func addTask() {
        let newTask = Task(context: viewContext)
        newTask.title = "New task \(tasks.count + 1)"
        newTask.createdAt = Date()
        try? viewContext.save()
    }

    private func toggleTask(_ task: Task) {
        task.isCompleted.toggle()
        try? viewContext.save()
    }

    private func deleteTasks(at offsets: IndexSet) {
        for index in offsets {
            viewContext.delete(tasks[index])
        }
        try? viewContext.save()
    }
}

Dieses Beispiel zeigt vollständiges CRUD mit @FetchRequest. Hinzufügen: Erstellen einer Task über den Kontext und save(). Löschen: delete() auf dem Kontext und save(). Aktualisieren: Umschalten einer Eigenschaft und save(). Nach jedem save() ruft @FetchRequest automatisch die Daten erneut ab, und die List wird animiert aktualisiert. Die Modifikatoren onDelete und onTapGesture bieten standardmäßige iOS-Interaktionen.

@FetchRequest Codebeispiele

Betrachten wir ein vollständiges Beispiel einer Tagebuch-Anwendung mit @FetchRequest zum Abrufen von Datensätzen. Das Suchformular verwendet ein dynamisches Prädikat: bei Texteingabe aktualisiert FetchRequest automatisch die Ergebnisse und filtert Datensätze nach Titel und Inhalt. Die Sortierung erfolgt nach Erstellungsdatum, vom neuesten zum ältesten.

swift
struct JournalEntryView: View {
    @Environment(\.managedObjectContext) var viewContext
    @State private var searchText = ""

    private var searchPredicate: NSPredicate? {
        guard !searchText.isEmpty else { return nil }
        return NSPredicate(format: "title CONTAINS[c] %@", searchText)
    }

    @FetchRequest var entries: FetchedResults<JournalEntry>

    init(searchText: String) {
        let sort = [NSSortDescriptor(keyPath: \.JournalEntry.date,
                                           ascending: false)]
        let pred: NSPredicate? = searchText.isEmpty
            ? nil
            : NSPredicate(format: "title CONTAINS[c] %@ OR content CONTAINS[c] %@",
                          searchText, searchText)
        self._entries = FetchRequest(
            sortDescriptors: sort,
            predicate: pred,
            animation: .default
        )
    }

    var body: some View {
        List(entries) { entry in
            VStack(alignment: .leading) {
                Text(entry.title ?? "").font(.headline)
                Text(entry.content ?? "").font(.subheadline)
                    .lineLimit(2)
            }
        }
        .searchable(text: $searchText)
    }
}

Tagebuch mit Suche: bei Texteingabe in das searchable-Feld wird ein NSPredicate mit CONTAINS[c] (Groß-/Kleinschreibung unwichtige Suche) in den Feldern title und content erstellt. Init akzeptiert searchText und erstellt einen FetchRequest mit dem entsprechenden Prädikat. Der searchable-Modifikator aktualisiert automatisch searchText, und @FetchRequest reagiert auf die Prädikatänderung und ruft die Daten erneut ab.

Für komplexere Szenarien mit mehreren Filtern kombinieren Sie NSCompoundPredicate mit AND/OR-Logik. @FetchRequest unterstützt Prädikate jeder Komplexität, einschließlich verschachtelter Unterabfragen (SUBQUERY) zur Filterung nach Relationship. Beachten Sie jedoch: komplexe Prädikate beeinträchtigen die Leistung — für große Datensätze (über 10.000 Datensätze) verwenden Sie Core Data Indizierung und begrenzen Sie den Abruf über fetchLimit.

Dynamische Prädikate zur Laufzeit

@FetchRequest unterstützt dynamische Prädikate über den Parameter predicate, der zur Laufzeit geändert werden kann. Dazu wird ein @FetchRequest mit einem variablen Prädikat erstellt und über Binding übergeben. Wenn der Benutzer den Filter ändert — zum Beispiel eine Aufgabenkategorie auswählt — wird das Prädikat aktualisiert und der Abruf automatisch neu gestartet.

Dynamische Prädikate werden über eine @State- oder @Published-Eigenschaft implementiert, die als Binding an den @FetchRequest-Initialisierer übergeben wird. SwiftUI verfolgt Änderungen an diesem Binding und erstellt den NSFetchRequest mit dem neuen Prädikat neu, wodurch die Liste automatisch aktualisiert wird.

Häufig gestellte Fragen

Wie übergibt man managedObjectContext an @FetchRequest?

Fügen Sie @Environment(\.managedObjectContext) var viewContext in der Root-View hinzu und übergeben Sie es über den .environment(\.managedObjectContext, context) Modifikator. Alle untergeordneten Views, die @FetchRequest verwenden, erhalten automatisch den Kontext aus der Umgebung.

Kann @FetchRequest ohne Neuladen der View aktualisiert werden?

Ja, ändern Sie den Core Data Kontext: fügen Sie ein Objekt hinzu, löschen oder aktualisieren Sie es und rufen Sie save() auf. @FetchRequest führt automatisch einen erneuten Abruf durch und aktualisiert die UI. Für eine erzwungene Aktualisierung ohne save() verwenden Sie viewContext.refreshAllObjects().

Was ist der Unterschied zwischen @FetchRequest und @SectionedFetchRequest?

@FetchRequest gibt ein flaches Array von Objekten zurück. @SectionedFetchRequest gruppiert Ergebnisse nach einem angegebenen Key Path in Abschnitte, ähnlich wie UITableView mit sectionNameKeyPath. Verwenden Sie @SectionedFetchRequest für gruppierte Listen mit Abschnittsüberschriften.

Wie verwendet man @FetchRequest mit Relationships?

Zum Filtern nach Relationship verwenden Sie die Punkt-Notation: NSPredicate(format: „category.name == %@“, „Work“). @FetchRequest führt automatisch einen JOIN in SQLite durch. Um auf eine Relationship über ein ausgewähltes Objekt zuzugreifen, verwenden Sie die normalen NSManagedObject-Eigenschaften.

Unterstützt @FetchRequest Paginierung?

@FetchRequest unterstützt keine direkte Paginierung, da es für die Anzeige aller Datensätze mit reaktiver Aktualisierung ausgelegt ist. Für Paginierung verwenden Sie NSFetchRequest mit fetchLimit/fetchOffset und laden Sie Daten manuell beim Scrollen der Liste.

Zusammenfassung

  • @FetchRequest — ein Property Wrapper für automatisches reaktives Core Data Abrufen in SwiftUI
  • Sortierung wird durch ein Array von NSSortDescriptor festgelegt, Filterung durch NSPredicate
  • Automatische Aktualisierung der UI bei Datenänderungen im Core Data Kontext
  • managedObjectContext wird über @Environment in der View-Hierarchie übergeben
  • Dynamische Prädikate werden über einen benutzerdefinierten Init mit Prädikatparameter implementiert
  • CRUD-Operationen werden über viewContext mit automatischer Listensynchronisation durchgeführt
  • Verwenden Sie @FetchRequest zur Anzeige von Core Data, @SectionedFetchRequest für gruppierte Listen

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch