Une fois que votre modèle a été adapté pour SwiftData, il est tout simple d'effectuer une requête pour afficher les données dans votre application.
Notez que la création de la base de données et de ses tables à partir des modèles est prise en charge par SwiftData.
Notez également que les données peuvent avoir été insérées par l'une de ces techniques :
Dans cette fiche :
Pour retrouver les données, il faut ajouter l'instruction import SwiftData dans le haut de la vue dans laquelle on désire effectuer une requête, par exemple ContentView.
Pour effectuer la requête, on déclarera une variable dans la vue à l'aide de la macro @Query.
import SwiftUI
import SwiftData
struct ContentView: View {
@Query var items: [Item]
var body: some View {
...
}
}
Ceci retournera un tableau de modèles.
Les modifications aux données de ce tableau forceront immédiatement le rafraîchissement de la vue, comme s'il s'agissait d'une variable d'état.
La requête sera effectuée dès l'affichage de la vue qui contient la macro @Query.
La variable ainsi initialisée peut être utilisée dans la vue au même titre que toute autre variable.
List {
ForEach(items) { item in
VStack(alignment: .leading) {
Text("\(item.code) - \(item.titre)")
}
}
}
Lorsqu'il y a une relation entre deux tables, les données de la secondes table pourront être retrouvées en enchaînant les objets.
Text(item.categorie.titre)
Notez qu'un tel enchaînement ne fonctionne qu'après l'exécution du @Query.
En effet, SwiftData ne supporte pas encore les jointures lors de la requête. Il est donc impossible de filtrer ou trier à l’aide d’une propriété d’une relation.
Ceci ne fonctionnera pas :
@Query() var items: [Item]
La variable initialisée par @Query (ici : items) est observable, c'est-à-dire que lorsque sa valeur change, les modifications sont reflétées automatiquement partout où la variable est utilisée, même dans une autre vue de l'application.
Ceci est pratique puisque lorsque vous modifiez des données de la base de données, par exemple lorsque vous faites un ajout ou une suppression, vous n'avez pas besoin de vous occuper de mettre la liste d'items à jour.
Button(action: {
...
modelContext.insert(item) // ceci ajoute l'item dans la BD et met à jour la variable items initialisée par @Query
...
}) {
Text("Enregistrer")
}
Comme pour toute application qui travaille avec des données, lorsque des informations doivent être affichées dans une application SwiftData, il faut que la requête les trie selon une des informations affichées.
@Query(sort: \Item.code) var items: [Item]
ou encore :
@Query(sort: \Item.code, order: .reverse) var items: [Item]
Si vous avez besoin de trier à l'aide de plus d'une clé, vous devrez travailler avec un SortDescriptor.
@Query(sort: [SortDescriptor(\Eleve.nomFamille), SortDescriptor(\Eleve.prenom)]) var eleves: [Eleve]
ou, pour faciliter la lecture du code :
@Query(
sort: [
SortDescriptor(\Eleve.nomFamille),
SortDescriptor(\Eleve.prenom)
]
)
var eleves: [Eleve]
Pour ne retrouver que certains enregistrements, on procédera comme suit :
@Query(filter: #Predicate<Item> { $0.titre.contains("A") }) var items: [Item]
Ou encore une combinaison de tri et de filtre :
@Query(filter: #Predicate<Item> { $0.titre.contains("A") }, sort: \Item.code) var items: [Item]
Lorsqu'on retrouve des données avec la macro @Query, il est possible de spécifier le type d'animation qui sera effectuée lorsque les données sont modifiées.
@Query(sort: \Item.code, order: .forward, animation: .linear) var items: [Item]
La macro @Query n'est disponible que dans une vue.
Si vous avez besoin d'effectuer une requête en dehors d'une vue, par exemple dans une méthode d'une classe, vous pouvez utiliser FetchDescriptor.
do {
let container = try ModelContainer(for: Item.self)
let descriptor = FetchDescriptor<Item>(
sortBy: [SortDescriptor(\.code)]
)
let items = try container.mainContext.fetch(descriptor)
...
}
catch {
print("Impossible de retrouver les items.")
}
« Filtering and sorting persistent data ». Apple. https://developer.apple.com/documentation/swiftdata/filtering-and-sorting-persistent-data
« How to Query and Filter Data in SwiftData with Predicate ». Swifty Place. https://www.swiftyplace.com/blog/fetch-and-filter-in-swiftdata
▼Publicité