@Published — is een property wrapper uit het Combine-framework die automatisch wijzigingen van een klasse-eigenschap publiceert die voldoet aan het ObservableObject-protocol. Wanneer de waarde van een met @Published gemarkeerde eigenschap verandert, ontvangt SwiftUI een signaal via objectWillChange en hertekent het alle views die op dit object zijn geabonneerd. Volgens Apple Combine Framework Documentation (2025) genereert @Published een Publisher die verder kan worden getransformeerd met Combine-operators: map, filter, debounce en andere. Dit maakt @Published tot een cruciale brug tussen gegevens en de gebruikersinterface in de MVVM-architectuur.
Belangrijkste punten
objectWillChange aangeroepen, wat het hertekenen van geabonneerde views triggert$property — men kan zich abonneren, combineren en de stroom transformeren@Published — is een property wrapper gedefinieerd in de Combine-module die aan een klasse-eigenschap de mogelijkheid toevoegt om abonnees automatisch op de hoogte te stellen van wijzigingen. Het kan alleen worden toegepast binnen een klasse (niet in een structuur) en alleen op eigenschappen van een klasse die voldoet aan het ObservableObject-protocol.
Wanneer de waarde van een @Published-eigenschap verandert, genereert Combine een gebeurtenis via de ingebouwde publisher, toegankelijk via het dollarteken: $propertyName. Deze publisher is ObservableObjectPublisher, die eigendom is van de ObservableObject zelf. SwiftUI abonneert zich er automatisch op wanneer een view @ObservedObject of @StateObject gebruikt, en hertekent de view bij elke wijziging van een @Published-eigenschap binnen het object.
Volgens het boek van Matt Neuburg „IOS 18 Programming Fundamentals with Swift” (2025) is @Published een handige wrapper rond het willSet-pattern, die automatisch objectWillChange.send() aanroept. Feitelijk vouwt de compiler @Published uit tot een berekende eigenschap met een willSet-observer, wat een nul overhead oplevert tijdens runtime in vergelijking met handmatige implementatie.
Gebruik @Published voor alle ObservableObject-eigenschappen waarvan wijzigingen in de interface moeten worden weerspiegeld. Voor eigenschappen die geen invloed hebben op de UI verminderen gewone stored properties zonder @Published het aantal onnodige hertekeningen.
@Published genereert twee belangrijke elementen tijdens compilatie. De eerste — een opgeslagen eigenschap met een willSet-observer die objectWillChange.send() aanroept voordat de nieuwe waarde wordt geschreven. De tweede — de projectie $propertyName die een Published.Publisher retourneert die direct in Combine-pijplijnen kan worden gebruikt.
Beschouw de klasse Settings met drie eigenschappen: twee @Published en een gewone:
class Settings: ObservableObject {
@Published var username: String = "Guest"
@Published var isDarkMode = false
var lastLogin: Date = Date() // zonder @Published
}
Bij wijziging van username of isDarkMode hertekent SwiftUI alle views die op de Settings-instantie zijn geabonneerd. Wijziging van lastLogin veroorzaakt geen hertekening. Als u abonnees handmatig wilt informeren over een wijziging van een gewone eigenschap, kunt u objectWillChange.send() aanroepen in de willSet-observer.
Een belangrijk detail: @Published publiceert wijzigingen alleen bij directe toewijzing aan de eigenschap. Als de eigenschap van een referentietype (klasse) is en de interne toestand verandert zonder de referentie te vervangen, zal @Published dit niet detecteren. In dergelijke gevallen is handmatige verzending van de gebeurtenis of vervanging door een waardetype (structuur) nodig.
@Published is nauw geïntegreerd met Combine — elke @Published-eigenschap biedt automatisch een publisher toegankelijk via de projectie $propertyName. Dit maakt het mogelijk om Combine-operators toe te passen voor filtering, transformatie, combinatie en vertraagde verwerking van waarden.
Een typisch scenario — zoeken met debounce. Het invoerveld is gekoppeld aan de @Published-eigenschap searchText, maar het verzoek aan de server mag pas worden verzonden na een pauze van 300 ms. Combine met $searchText.debounce lost dit in één regel op:
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) { }
}
Volgens het artikel van John Sundell (Swift by Sundell, 2024) is het combineren van @Published met Combine een standaardpatroon voor reactieve pijplijnen in SwiftUI-applicaties: validation, debounce, throttle, combineLatest, merge met andere publishers. @Published fungeert als een brug tussen imperatieve UI-code en reactieve Combine.
Met de release van iOS 17 introduceerde Apple de @Observable-macro, die een alternatieve benadering van reactiviteit biedt zonder ObservableObject en @Published. @Observable volgt automatisch de toegang tot eigenschappen op leesniveau, niet op schrijfniveau, wat nauwkeurigere hertekeningen oplevert — alleen de view die de specifiek gewijzigde eigenschap leest, wordt bijgewerkt.
Maar dit betekent niet dat @Published verouderd is. @Published blijft noodzakelijk wanneer integratie met Combine-pijplijnen nodig is — de projectie $propertyName biedt een publisher die @Observable niet heeft. Bovendien is @Published+ObservableObject de enige optie voor achterwaartse compatibiliteit met iOS 16 en lager. Volgens de Apple WWDC 2023-sessie „Discover Observation in SwiftUI” beveelt Apple @Observable aan voor nieuwe projecten, maar behoudt expliciet ondersteuning voor @Published voor bestaande code en Combine-scenario’s.
In de praktijk gebruiken veel projecten een hybride aanpak: nieuwe gegevensmodellen worden geschreven met @Observable, terwijl bestaande ObservableObject met @Published blijven zonder refactoring. @Published is ook onmisbaar wanneer fijne controle over de publicatie nodig is — bijvoorbeeld het uitstellen van een melding tot de voltooiing van een batch-update van meerdere eigenschappen.
Eerste fout — @Published toepassen in een structuur. De compiler geeft een foutmelding: „Property wrapper cannot be applied to a computed property” of „'@Published' is only available on members of a class”. @Published vereist referentiesemantiek, omdat ObservableObjectPublisher een klasse is die uniek moet zijn voor elke instantie.
Tweede fout — mutatie van de inhoud van een referentie-eigenschap zonder de referentie te vervangen. Als een @Published-eigenschap van het type array [String] is en u roept array.append("new") aan, zal @Published de wijziging niet detecteren omdat de referentie naar de array niet is veranderd. Oplossing: ken een nieuwe waarde toe aan de eigenschap array = array + ["new"] of gebruik handmatig objectWillChange.send().
Derde fout — overmatig aantal @Published-eigenschappen. Elke @Published-eigenschap veroorzaakt het hertekenen van alle views die op de ObservableObject zijn geabonneerd, niet alleen die welke deze eigenschap lezen. Volgens Point-Free (2025) vermindert het splitsen van een grote ObservableObject in meerdere kleine met @StateObject en @EnvironmentObject het aantal onnodige hertekeningen en verbetert de prestaties.
Eerste voorbeeld — ViewModel van een registratieformulier met validatie. De @Published-eigenschappen email en password triggeren de weergave van validatiefouten via de Combine-pijplijn:
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)
}
}
Tweede voorbeeld — handmatige publicatie voor een verzameling referentie-elementen. In plaats van de hele array te vervangen bij elke wijziging binnen een element, wordt objectWillChange.send() gebruikt:
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() // handmatige melding
}
}
Derde voorbeeld — Assign naar een @Published-eigenschap via Combine. Met de nieuwe syntaxis van Swift 5.9 kan men direct toewijzen via de projectie assign(to: &$property) zonder Optional-wrapper. Dit is de kortste weg om een publisher te koppelen aan een @Published-eigenschap zonder een abonnement te creëren.
Veelgestelde vragen
Nee, @Published kan alleen worden toegepast binnen een klasse die voldoet aan ObservableObject. Gebruik in structuren @State voor lokale toestand of @Bindable met de @Observable-macro in iOS 17+. Een poging om @Published in een structuur toe te passen, veroorzaakt een compilatiefout.
Correct: ken een nieuwe waarde in zijn geheel toe (array = array + ["new"]). @Published volgt de vervanging van de referentie, niet de mutatie van de inhoud. Gebruik voor verzamelingen van referentietypen de handmatige aanroep objectWillChange.send() na mutatie van de interne toestand van elementen.
@State is bedoeld voor lokale toestand binnen één view en werkt alleen met waardetypen. @Published — voor ObservableObject-eigenschappen die door meerdere views kunnen worden gelezen via @ObservedObject of @EnvironmentObject. @State is eenvoudiger, @Published is krachtiger dankzij de integratie met Combine.
Alleen voor die waarvan wijzigingen de UI moeten bijwerken. Eigenschappen voor interne berekeningen, cache of tijdelijke vlaggen vereisen geen @Published — dit vermindert het aantal onnodige hertekeningen. Gebruik @Published als een signaal „deze eigenschap is belangrijk voor de interface”.
SwiftUI integreert met Core Data via @FetchRequest en @ObservedObject voor NSManagedObject. ManagedObject voldoet al aan ObservableObject, dus @Published is niet nodig — NSManagedObject zelf meldt wijzigingen. @Published wordt gebruikt in de ViewModel-laag tussen Core Data en UI voor gegevenstransformatie.
Samenvatting
objectWillChange.send() aan, genereert een publisher via de projectie $propertyassign(to: &$property) in Swift 5.9 maakt het mogelijk om een publisher direct op een @Published-eigenschap te abonnerenWe ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook