Core Data — ce que c'est, modèle de données et comment ça fonctionne

Auteur : IT Sectr Publié le : 2026-05-04 Temps de lecture : 8 min

Core Data est un framework de gestion de données d'Apple fournissant un mapping objet-relationnel pour iOS, macOS, tvOS et watchOS. Il automatise la sauvegarde, la récupération et le filtrage des objets dans l'application, fonctionnant au-dessus de SQLite, XML ou de stockage binaire. Selon la Apple Core Data Documentation, le framework utilise les concepts de Managed Object Context et NSPersistentContainer pour gérer la pile de persistance.

Points clés

  • Core Data — framework d'Apple pour la gestion objet-relationnelle des données dans les applications.
  • NSManagedObjectModel — description du schéma de données : Entity, Attributes et Relationships.
  • NSManagedObject — objet correspondant à un enregistrement dans le magasin Core Data.
  • NSManagedObjectContext — espace de travail pour créer, lire et sauvegarder des objets.
  • NSPersistentContainer — pile unifiée combinant le modèle, le contexte et le coordinateur de stockage.

Qu'est-ce que Core Data et son rôle dans iOS

Core Data est un framework de gestion de graphe d'objets et de persistance faisant partie de Cocoa Touch. Contrairement à une idée reçue, Core Data n'est pas une base de données, mais une couche de gestion d'objets qui peut utiliser SQLite comme l'un de ses magasins. La tâche principale de Core Data est de suivre les modifications des objets, de gérer leur cycle de vie et de synchroniser l'état avec le disque.

Le framework fournit un graphe d'objets où chaque Managed Object est surveillé par le contexte pour détecter les modifications. Lors de la sauvegarde, tous les objets modifiés, ajoutés et supprimés sont validés dans le magasin persistant en une seule transaction. Cela élimine la nécessité pour le développeur d'écrire des requêtes SQL et de gérer manuellement les transactions.

Selon les statistiques de l'enquête Swift Developer Survey (2025), Core Data est utilisé dans 52% des applications iOS travaillant avec des données locales. Malgré l'émergence d'alternatives modernes (SwiftData, Realm), Core Data reste le framework principal dans les projets Apple existants grâce à sa maturité et son intégration profonde avec le système.

Utilisez Core Data pour les projets avec un modèle de données de complexité moyenne où des relations entre objets, l'annulation de modifications et la mise en cache automatique via le mécanisme de faulting sont nécessaires.

L'architecture de Core Data est construite autour du concept de Managed Object Context — un espace de travail qui suit toutes les modifications des objets. Le contexte prend en charge l'annulation/répétition via le NSUndoManager intégré, permettant d'implémenter des brouillons et l'annulation d'actions sans sauvegarder manuellement des instantanés d'état. Lors de l'appel à save(), le contexte valide toutes les modifications en une seule transaction dans le magasin persistant, garantissant l'atomicité et la cohérence des données.

Modèle de données : Entity, Attributes, Relationships

Le modèle de données Core Data est défini dans le fichier .xcdatamodeld — l'éditeur visuel de Xcode où toutes les Entity, leurs attributs et relations sont décrits. À la compilation, le modèle est sérialisé en .momd et chargé via NSManagedObjectModel.

Entity et Attributes

Entity est une description de type de données, similaire à une table en SQL. Chaque Entity contient un ensemble d'Attributes — des champs nommés avec un type de données (String, Integer, Date, Boolean, Data). Contrairement à Room, Core Data nécessite une sélection explicite du type pour chaque attribut via l'éditeur de modèle.

Relationships

Relationship est une connexion entre Entity, similaire à une clé étrangère en SQL. Core Data prend en charge tous les types de relations : un-à-un, un-à-plusieurs et plusieurs-à-plusieurs. Pour chaque relation, une Delete Rule (Cascade, Nullify, Deny) est configurée — le comportement lors de la suppression de l'objet associé.

Delete RuleComportement lors de la suppressionExemple d'utilisation
CascadeSupprime tous les objets associésSupprimer une commande avec ses articles
NullifyAnnule la relation inverseSupprimer un auteur sans supprimer les livres
DenyBloque la suppression si des objets associés existentProtéger contre la suppression d'une catégorie avec des produits

Choisir une Delete Rule est crucial pour l'intégrité des données : Cascade sans vérification peut supprimer un tiers de la base de données, tandis que Deny peut bloquer l'opération avec une erreur peu claire. Dans le code de production, Nullify avec un traitement manuel des enregistrements orphelins est recommandé.

Dans l'éditeur de modèle de Xcode, le développeur peut définir non seulement les Entity et les attributs, mais aussi les constraints (contraintes d'unicité), les index pour accélérer les requêtes et les valeurs par défaut pour les attributs. Toutes les modifications du modèle sont compilées dans un fichier .momd, qui est chargé lors de l'initialisation de NSPersistentContainer. Le versionnement de modèle (Model Versioning) permet de maintenir plusieurs versions du schéma et d'effectuer une migration entre elles.

Pile Core Data : PersistentContainer et Context

NSPersistentContainer est un objet unique qui gère la pile Core Data depuis iOS 10 et macOS 10.12. Il encapsule NSManagedObjectModel, NSPersistentStoreCoordinator et NSManagedObjectContext, automatisant le chargement du modèle et la configuration du magasin. Pour les versions plus anciennes, la pile était construite manuellement, mais ce n'est plus recommandé.

swift
let container = NSPersistentContainer(name: "DataModel")
container.loadPersistentStores { _, error in
    if let error { fatalError("Core Data load failed: \(error)") }
}
let context = container.viewContext

viewContext est le contexte principal lié au thread principal. Toutes les lectures et mises à jour de l'interface sont effectuées via lui. Pour les performances, il est recommandé d'effectuer l'écriture des données dans un contexte fils en arrière-plan avec synchronisation ultérieure.

NSPersistentStoreCoordinator

Le coordinateur NSPersistentStoreCoordinator relie le modèle au stockage physique sur disque. Core Data prend en charge plusieurs types de magasins : SQLite (recommandé), Binary et In-Memory. Le magasin SQLite prend en charge les migrations, la sauvegarde incrémentielle et la résistance aux pannes lors des opérations d'écriture.

NSFetchRequest et travail avec les données

NSFetchRequest est un objet décrivant une requête au magasin Core Data. Il contient le nom de l'Entity, le prédicat de filtrage, les descripteurs de tri et les paramètres de récupération. La requête est exécutée via context.fetch(), qui retourne un tableau de NSManagedObject.

swift
let request = NSFetchRequest<User>(entityName: "User")
request.predicate = NSPredicate(format: "age >= %d", 18)
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
request.fetchLimit = 50

let results = try context.fetch(request)

NSPredicate prend en charge des conditions complexes : LIKE, IN, BETWEEN, CONTAINS[c] (insensible à la casse), SUBQUERY pour les requêtes imbriquées sur des Entity associées. Core Data prend également en charge NSFetchedResultsController — une classe pour le chargement réactif de données dans UITableView, qui suit automatiquement les modifications et met à jour la table avec des sections animées.

Core Data dans un environnement multi-thread

Travailler avec Core Data dans une application multi-thread nécessite le respect strict des règles : NSManagedObject ne peut pas être passé directement entre les threads. Chaque thread (ou file d'attente) doit utiliser son propre contexte. L'approche principale consiste à créer un NSManagedObjectContext fils avec une file d'attente privée (NSPrivateQueueConcurrencyType) pour l'écriture et viewContext pour la lecture.

Le contexte fils sauvegarde dans le parent, puis le parent sauvegarde dans le magasin sur disque. Cela garantit que les modifications ne bloquent pas le thread principal et que l'interface utilisateur voit toujours un état cohérent via mergeChanges ou la mise à jour automatique de viewContext lors de la sauvegarde.

Core Data utilise le faulting — un mécanisme de chargement différé pour les objets associés. Lors de la récupération d'un User sans demander ses adresses, les objets Address associés ne sont pas chargés tant qu'ils ne sont pas accédés via la notation pointée. Le faulting économise la mémoire et accélère le chargement, mais peut provoquer des accès inattendus au disque sur le thread principal si l'accès n'est pas contrôlé dans les contextes d'arrière-plan.

Pour un multi-threading efficace, utilisez NSBatchInsertRequest et NSBatchDeleteRequest pour les insertions et suppressions en masse sans charger les objets en mémoire — c'est essentiel pour la synchronisation des données avec le serveur.

Les opérations par lots s'exécutent directement au niveau de NSPersistentStoreCoordinator, en contournant le contexte et le graphe d'objets. Cela permet d'insérer 10 000 enregistrements en quelques millisecondes sans créer 10 000 instances NSManagedObject en mémoire. Après l'exécution d'une requête par lots, le contexte doit être mis à jour via mergeChangesFromContextDidSaveNotification pour que l'interface utilisateur reflète les nouvelles données. Apple recommande les opérations par lots pour le chargement initial des données et la synchronisation nocturne avec le serveur.

Pour le suivi des modifications dans Core Data, on utilise NSPersistentHistoryTracking — un mécanisme qui enregistre chaque transaction (insertion, mise à jour, suppression) dans un historique séparé. L'activation du suivi d'historique permet de synchroniser les données entre différents processus et applications travaillant avec le même fichier SQLite, par exemple entre l'application principale et une Notification Service Extension. L'activation se fait via NSPersistentStoreDescription avec le flag persistentHistoryTrackingKey, et la lecture via NSPersistentHistoryChangeRequest avec filtrage par date et type de transaction.

Pour le débogage et le profilage des performances de Core Data, on utilise l'outil Core Data Profiler de la suite Instruments dans Xcode sur macOS. Il affiche toutes les opérations de récupération, d'insertion, de suppression et de sauvegarde avec la durée de chaque opération et le nombre d'objets chargés dans des tableaux et des graphiques chronologiques. Le développeur peut identifier les zones problématiques : plusieurs récupérations de la même requête (absence de cache), fuites d'objets fault lors du défilement de la table ou blocage du thread principal dû au chargement synchrone d'entités associées. Il est recommandé d'exécuter le profilage sur un appareil réel et non sur un simulateur, car les performances du simulateur ne reflètent pas le comportement réel de l'application sur un iPhone ou un iPad.

Questions fréquentes

Quelle est la différence entre Core Data et SQLite ?

Core Data n'est pas une base de données, mais une couche de gestion d'objets qui peut utiliser SQLite comme magasin. Contrairement à SQLite pur, Core Data suit les modifications des objets, gère l'annulation et fournit un graphe d'objets avec faulting et mise en cache. SQLite offre plus de contrôle sur les requêtes, mais nécessite d'écrire du SQL et de gérer manuellement les transactions.

Comment effectuer la migration de schéma Core Data ?

Core Data prend en charge la migration légère (Lightweight Migration) pour les modifications non destructives : ajout d'un attribut, renommage, définition d'une valeur par défaut. Pour les modifications complexes, un Mapping Model est créé. La migration légère est activée par le flag shouldMigrateAutomatically dans NSPersistentStoreDescription.

Peut-on utiliser Core Data avec SwiftUI ?

Oui, Core Data s'intègre avec SwiftUI via le wrapper @FetchRequest pour les requêtes et @ObservedObject pour l'abonnement aux modifications. SwiftUI met automatiquement à jour la View lorsqu'un ManagedObject change, faisant de Core Data et SwiftUI une pile compatible pour la gestion d'état.

Qu'est-ce qu'un fault dans Core Data ?

Un fault est un placeholder léger dans le graphe Core Data qui ne contient pas les données de l'objet associé. Lorsqu'un fault est défini (via refreshObject:), les données sont déchargées de la mémoire. Lors de l'accès à une propriété, le fault se remplit automatiquement avec les données du magasin — c'est un mécanisme de chargement différé qui optimise l'utilisation de la mémoire.

Comment tester le code Core Data ?

Pour les tests, utilisez le type de magasin In-Memory : NSPersistentStoreDescription avec NSInMemoryStoreType. Le conteneur est créé avec le modèle du bundle de test. Après chaque test, supprimez tous les objets ou recréez le conteneur — cela garantit l'isolation des cas de test les uns des autres.

Résumé

  • Core Data est un framework de gestion de graphe d'objets utilisant SQLite comme magasin par défaut.
  • NSManagedObjectModel décrit le schéma : Entity, Attributes, Relationships et Delete Rules.
  • NSPersistentContainer combine le modèle, le coordinateur et viewContext en une pile unifiée.
  • NSFetchRequest avec NSPredicate et NSSortDescriptor forme des requêtes flexibles au magasin.
  • Le multi-threading nécessite des contextes séparés : un contexte fils pour l'écriture et viewContext pour la lecture.
  • Faulting diffère le chargement des objets associés jusqu'au premier accès, économisant la mémoire.
  • Lightweight Migration gère automatiquement les modifications de schéma non destructives sans perte de données.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi