@Published : qu'est-ce que c'est, principe de fonctionnement et application

Auteur : IT Sectr Publié le : 2026-06-19 Temps de lecture : 8 min

@Published est un « property wrapper » du framework Combine qui publie automatiquement les modifications d'une propriété de classe conforme au protocole ObservableObject. Lorsque la valeur d'une propriété marquée avec @Published change, SwiftUI reçoit un signal via objectWillChange et redessine toutes les vues abonnées à cet objet. Selon la documentation Apple Combine Framework (2025), @Published génère un Publisher qui peut être davantage transformé via les opérateurs Combine : map, filter, debounce et autres. Cela fait de @Published un pont clé entre les données et l'interface utilisateur dans l'architecture MVVM.

Points clés

  • @Published — « property wrapper » pour la publication automatique des modifications des propriétés ObservableObject dans SwiftUI et Combine
  • Mécanisme : lorsque la valeur change, objectWillChange est appelé, ce qui déclenche le redessin des vues abonnées
  • Publisher accessible via la projection $property — on peut s'abonner, combiner et transformer le flux
  • ObservedObject et StateObject s'abonnent automatiquement aux propriétés @Published — aucun abonnement manuel requis
  • iOS 17+ la macro @Observable offre une alternative, mais @Published reste la norme pour les pipelines Combine

Qu'est-ce que @Published ?

@Published est un « property wrapper » défini dans le module Combine qui ajoute la possibilité de notifier automatiquement les abonnés des modifications d'une propriété de classe. Il ne peut être utilisé qu'à l'intérieur d'une classe (pas dans une structure) et uniquement sur les propriétés d'une classe conforme au protocole ObservableObject.

Lorsque la valeur d'une propriété @Published change, Combine génère un événement via un publisher intégré accessible via le préfixe dollar : $propertyName. Ce publisher est un ObservableObjectPublisher, qui appartient à l'ObservableObject lui-même. SwiftUI s'y abonne automatiquement lorsqu'une vue utilise @ObservedObject ou @StateObject, et redessine la vue à chaque fois qu'une propriété @Published dans l'objet change.

Selon le livre de Matt Neuburg « IOS 18 Programming Fundamentals with Swift » (2025), @Published est un wrapper pratique sur le modèle willSet, appelant automatiquement objectWillChange.send(). En effet, le compilateur développe @Published en une propriété calculée avec un observateur willSet, ce qui ne génère aucun surcoût d'exécution par rapport à une implémentation manuelle.

Utilisez @Published pour toutes les propriétés ObservableObject dont les modifications doivent être reflétées dans l'interface. Pour les propriétés qui n'affectent pas l'UI, les propriétés stockées ordinaires sans @Published réduisent les redessins inutiles.

Comment fonctionne @Published

@Published génère deux éléments clés à la compilation. Le premier est une propriété stockée avec un observateur willSet qui appelle objectWillChange.send() avant d'écrire la nouvelle valeur. Le second est la projection $propertyName, qui retourne un Published.Publisher qui peut être utilisé directement dans les pipelines Combine.

Considérez la classe Settings avec trois propriétés : deux @Published et une normale :

swift
class Settings: ObservableObject {
    @Published var username: String = "Guest"
    @Published var isDarkMode = false
    var lastLogin: Date = Date()  // without @Published
}

Lorsque username ou isDarkMode change, SwiftUI redessinera toutes les vues abonnées à l'instance Settings. La modification de lastLogin ne déclenchera pas de redessin. Si vous devez notifier manuellement les abonnés d'un changement sur une propriété normale, vous pouvez appeler objectWillChange.send() dans l'observateur willSet.

Un détail important : @Published ne publie les changements que lorsqu'une propriété est directement assignée. Si la propriété est d'un type référence (classe) et que son état interne change sans remplacer la référence, @Published ne le détectera pas. Dans de tels cas, l'envoi manuel d'événements ou le passage à un type valeur (structure) est nécessaire.

@Published et Combine

@Published est étroitement intégré avec Combine — chaque propriété @Published fournit automatiquement un publisher accessible via la projection $propertyName. Cela permet d'utiliser les opérateurs Combine pour filtrer, transformer, combiner et traiter les valeurs de manière différée.

Un scénario typique est la recherche avec debounce. Un champ de saisie est lié à la propriété @Published searchText, mais la requête au serveur ne doit être envoyée qu'après une pause de 300 ms. Combine avec $searchText.debounce résout cela en une ligne :

swift
class SearchViewModel: ObservableObject {
    @Published var searchText = ""
    @Published var results: [String] = []
    private var cancellables = Set<AnyCancellable>()

    init() {
        setupSearchSubscription()
    }

    private func setupSearchSubscription() {
        $searchText
            .debounce(for: .milliseconds(300), scheduler: RunLoop.main)
            .removeDuplicates()
            .sink { [weak self] text in
                self?.performSearch(text)
            }
            .store(in: &cancellables)
    }

    private func performSearch(_ text: String) { }
}

Selon l'article de John Sundell (Swift by Sundell, 2024), combiner @Published avec Combine est un modèle standard pour les pipelines réactifs dans les applications SwiftUI : validation, debounce, throttle, combineLatest, merge avec d'autres publishers. @Published agit comme un pont entre le code UI impératif et Combine réactif.

@Published vs macro @Observable

Avec la sortie d'iOS 17, Apple a introduit la macro @Observable, qui offre une approche alternative de la réactivité sans ObservableObject ni @Published. @Observable suit automatiquement l'accès aux propriétés au niveau de la lecture plutôt que de l'écriture, offrant des redessins plus précis — seule la vue qui lit une propriété modifiée spécifique est mise à jour.

Cependant, cela ne signifie pas que @Published est obsolète. @Published reste nécessaire lorsque l'intégration avec les pipelines Combine est requise — la projection $propertyName fournit un publisher que @Observable n'a pas. De plus, pour la compatibilité ascendante avec iOS 16 et inférieur, @Published+ObservableObject est la seule option. Selon la session Apple WWDC 2023 « Discover Observation in SwiftUI », Apple recommande @Observable pour les nouveaux projets, mais maintient explicitement le support de @Published pour le code existant et les scénarios Combine.

En pratique, de nombreux projets utilisent une approche hybride : les nouveaux modèles de données utilisent @Observable, tandis que les ObservableObject existants avec @Published restent sans refactorisation. @Published est également indispensable lorsqu'un contrôle précis sur la publication est nécessaire — par exemple, retarder la notification jusqu'à ce qu'une mise à jour par lot de plusieurs propriétés soit terminée.

Erreurs courantes avec @Published

La première erreur est l'utilisation de @Published dans une structure. Le compilateur générera une erreur : « Property wrapper cannot be applied to a computed property » ou « '@Published' is only available on members of a class. » @Published nécessite une sémantique de référence car ObservableObjectPublisher est une classe qui doit être unique pour chaque instance.

La deuxième erreur est la mutation du contenu d'une propriété de référence sans remplacer la référence. Si une propriété @Published est de type tableau [String] et que vous appelez array.append("nouveau"), @Published ne détectera pas le changement car la référence au tableau n'a pas changé. Solution : assignez une nouvelle valeur à la propriété array = array + ["nouveau"] ou utilisez objectWillChange.send() manuellement.

La troisième erreur est un nombre excessif de propriétés @Published. Chaque propriété @Published déclenche un redessin de toutes les vues abonnées à l'ObservableObject, pas seulement celles qui lisent cette propriété. Selon Point-Free (2025), diviser un grand ObservableObject en plusieurs plus petits avec @StateObject et @EnvironmentObject réduit les redessins inutiles et améliore les performances.

Exemples de code

Le premier exemple est un ViewModel de formulaire d'inscription avec validation. Les propriétés @Published email et password déclenchent l'affichage des erreurs de validation via un pipeline Combine :

swift
class RegistrationViewModel: ObservableObject {
    @Published var email = ""
    @Published var password = ""
    @Published var emailError: String?
    @Published var isFormValid = false
    private var cancellables = Set<AnyCancellable>()

    init() {
        $email
            .map { $0.contains("@") ? nil : "Invalid email" }
            .assign(to: &$emailError)
            .store(in: &cancellables)

        $email.combineLatest($password)
            .map { !$0.isEmpty && !$1.isEmpty }
            .assign(to: &$isFormValid)
            .store(in: &cancellables)
    }
}

Le deuxième exemple est la publication manuelle pour une collection d'éléments de référence. Au lieu de remplacer tout le tableau à chaque changement dans un élément, objectWillChange.send() est utilisé :

swift
class TodoItem {
    var title: String
    var isDone = false
    init(title: String) { self.title = title }
}

class TodoListViewModel: ObservableObject {
    @Published var items: [TodoItem] = []

    func toggle(item: TodoItem) {
        item.isDone.toggle()
        self.objectWillChange.send()  // manual notification
    }
}

Le troisième exemple est Assign à une propriété @Published via Combine. En utilisant la nouvelle syntaxe Swift 5.9, vous pouvez assigner directement via la projection assign(to: &$property) sans wrapper Optional. C'est le moyen le plus court de connecter un publisher à une propriété @Published sans créer d'abonnement.

Foire aux questions

Peut-on utiliser @Published dans une structure ?

Non, @Published ne peut être utilisé qu'à l'intérieur d'une classe conforme à ObservableObject. Dans les structures, utilisez @State pour l'état local ou @Bindable avec la macro @Observable dans iOS 17+. Essayer d'utiliser @Published dans une structure provoquera une erreur de compilation.

Comment @Published fonctionne-t-il avec les tableaux et les dictionnaires ?

Approche correcte : assignez la nouvelle valeur entièrement (array = array + ["nouveau"]). @Published suit le remplacement de la référence, pas la mutation du contenu. Pour les collections de types référence, utilisez l'appel manuel objectWillChange.send() après avoir muté l'état interne des éléments.

En quoi @Published diffère-t-il de @State ?

@State est conçu pour l'état local au sein d'une seule vue et fonctionne uniquement avec les types valeur. @Published est pour les propriétés ObservableObject qui peuvent être lues par plusieurs vues via @ObservedObject ou @EnvironmentObject. @State est plus simple, @Published est plus puissant grâce à l'intégration avec Combine.

Chaque propriété ObservableObject a-t-elle besoin de @Published ?

Seulement celles dont les modifications doivent mettre à jour l'UI. Les propriétés pour les calculs internes, les caches ou les indicateurs temporaires n'ont pas besoin de @Published — cela réduit les redessins inutiles. Utilisez @Published comme un signal que « cette propriété est importante pour l'interface ».

Comment @Published fonctionne-t-il avec Core Data ?

SwiftUI s'intègre avec Core Data via @FetchRequest et @ObservedObject pour NSManagedObject. ManagedObject est déjà conforme à ObservableObject, donc @Published n'est pas nécessaire — NSManagedObject notifie les changements par lui-même. @Published est utilisé dans la couche ViewModel entre Core Data et l'UI pour la transformation des données.

Résumé

  • @Published — « property wrapper » de Combine qui publie automatiquement les modifications des propriétés ObservableObject pour SwiftUI et les pipelines Combine
  • Mécanisme : un observateur willSet appelle objectWillChange.send(), générant un publisher via la projection $property
  • Combine : @Published fournit un publisher pour debounce, map, combineLatest et d'autres opérateurs — un pont entre l'UI et les pipelines réactifs
  • @Observable (iOS 17+) — une alternative pour les nouveaux projets, mais @Published reste la norme pour Combine et la compatibilité ascendante
  • Erreurs : @Published ne fonctionne pas dans les structures, ne suit pas la mutation des types référence, un excès de propriétés @Published augmente les redessins
  • Meilleure pratique : marquez uniquement les propriétés affectant l'UI avec @Published, divisez les grands ObservableObject en plusieurs plus petits
  • Assign : assign(to: &$property) dans Swift 5.9 permet d'abonner un publisher directement à une propriété @Published

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