Formation PUB900 : Développer une application pour iPhone avec SwiftUI, H-2024 SwiftData

37.4 Adapter le modèle et l'application pour SwiftData


Lorsque vous travaillez avec SwiftData, le modèle doit être défini dans une classe spéciale.

Lorsque l'application sera lancée, SwiftData créera automatiquement la base de données avec les tables qui correspondent aux modèles listés dans le modelContainer.

Voici un exemple d'un modèle SwiftData :

Fichier Models/Item.swift

import Foundation
import SwiftData

@Model
final class Item {
  var code: String
  var titre: String
  var dateAjout: Date


  init(code: String = "", titre: String = "", dateAjout: Date = Date()) {
    self.code = code
    self.titre = titre
    self.dateAjout = dateAjout
  }
}

Remarquez l'utilisation du type Date pour stocker une date, même si les dates en SQLite sont stockées sous forme de texte.

SwiftData fera le nécessaire pour faire la conversion entre ces deux formats.

Ajustement du modèle

Si vous avez déjà codé un modèle, vous devez apporter quelques ajustements pour qu'il se conforme aux exigences de SwiftData. 

  • ajouter l'instruction import SwiftData
  • modifier le mot-clé struct pour class
  • ajouter la macro @Model juste avant la définition de la classe
  • définir au moins un constructeur puisque les classes n'ont pas de constructeur par défaut
  • vous n'avez pas besoin de spécifier l'attribut id ni de répondre au protocole Identifiable, tout cela est géré automatiquement par SwiftData.
  • ceci est optionnel mais permet d'améliorer légèrement les performances : marquer la classe avec final
Fichier Models/Item.swift
import Foundation

import SwiftData

@Model
final class Item: Identifiable {
  var id: Int
  var code: String
  var titre: String
  var dateAjout: Date

  // le constructeur est requis dans une classe
  init(code: String = "", titre: String = "", dateAjout: Date = Date()) {
    self.code = code
    self.titre = titre
    self.dateAjout = dateAjout
  }
}

La macro @Model semble anodine, mais elle joue un rôle important.

Elle crée litéralement beaucoup de code pour vous afin que le modèle interagisse avec une table de la base de données.

Si vous êtes curieux de voir le code ajouté, vous pouvez faire un clic droit sur le mot @Model puis choisir Expand Macro.

Ne vous laissez pas impressionner par le code ajouté, il peut demeurer caché (clic droit / Hide Macro Expansion) et vous pourrez tout de même travailler efficacement avec SwiftData.

Lister les modèles dans le modelContainer

Dans le fichier de l'application (fichier dont le nom est au format MonProjetApp.swift), vous devez spécifier quels modèles doivent être utilisés par SwiftData :

  • ajoutez l'instruction import SwiftData
  • ajoutez ceci à WindowGroup.modelContainer(for: Item.self) (remplacer Item par le nom de votre modèle)
Fichier MonProjetApp.swift

import SwiftUI
import SwiftData

@main
struct MonProjetApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView()
    }
    .modelContainer(for: Item.self)
  }
}

Application avec plusieurs tables

Lorsqu'une application utilise plusieurs tables, donc plusieurs modèles, il y a deux figures de cas :

  • Si l'un des modèles a une relation avec l'autre modèle, par exemple un Item a une propriété de type Categorie, il n'est pas nécessaire de faire référence à Categorie car SwiftData retrouvera cette information tout seul.
  • Si rien ne relie deux modèles, il suffit de les faire suivre comme suit :
    Fichier MonProjetApp.swift

    import SwiftUI
    import SwiftData

    @main
    struct MonProjetApp: App {
      var body: some Scene {
        WindowGroup {
          ContentView()
        }
        .modelContainer(for: [Item.self, Usager.self])
      }
    }

Application avec données initiales

Dans le cas où l'application se charge d'insérer des données initiales dans la base de données, l'approche est légèrement différente.

On fera tout de même appel à .modelContainer mais plutôt que de lui passer les modèles en paramètre, on fera appel au conteneur qui est responsable de l'insertion des données (ici, il s'appelle preloadAppContainer).

Fichier MonProjetApp.swift

import SwiftUI
import SwiftData

@main
struct MonProjetApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView()
    }
    .modelContainer(preloadAppContainer)
  }
}

Pour plus d'information

« Defining a data model with SwiftData ». Hacking with Swift. https://www.hackingwithswift.com/quick-start/swiftdata/defining-a-data-model-with-swiftdata

« Why are SwiftData models created as classes? ». Hacking with Swift. https://www.hackingwithswift.com/quick-start/swiftdata/why-are-swiftdata-models-created-as-classes

▼Publicité

Veuillez noter que le contenu de cette fiche vous est partagé à titre gracieux, au meilleur de mes connaissances et sans aucune garantie.
Merci de partager !
Soumettre