@Published — adalah property wrapper dari framework Combine yang secara otomatis memublikasikan perubahan properti kelas yang sesuai dengan protokol ObservableObject. Ketika nilai properti yang ditandai dengan @Published berubah, SwiftUI menerima sinyal melalui objectWillChange dan menggambar ulang semua view yang berlangganan ke objek ini. Menurut Apple Combine Framework Documentation (2025), @Published menghasilkan Publisher yang dapat ditransformasikan lebih lanjut melalui operator Combine: map, filter, debounce, dan lainnya. Hal ini menjadikan @Published sebagai jembatan utama antara data dan antarmuka pengguna dalam arsitektur MVVM.
Poin Utama
objectWillChange dipanggil, yang memicu penggambaran ulang view yang berlangganan$property — dapat berlangganan, menggabungkan, dan mentransformasi aliran@Published — adalah property wrapper yang didefinisikan dalam modul Combine yang menambahkan kemampuan ke properti kelas untuk secara otomatis memberi tahu pelanggan tentang perubahan. Ini hanya dapat diterapkan di dalam kelas (bukan di struct) dan hanya pada properti kelas yang sesuai dengan protokol ObservableObject.
Ketika nilai properti @Published berubah, Combine menghasilkan peristiwa melalui publisher bawaan, yang dapat diakses melalui prefiks dolar: $propertyName. Publisher ini adalah ObservableObjectPublisher, yang dimiliki oleh ObservableObject itu sendiri. SwiftUI secara otomatis berlangganan padanya ketika view menggunakan @ObservedObject atau @StateObject, dan menggambar ulang view pada setiap perubahan properti @Published di dalam objek.
Menurut buku Matt Neuburg „IOS 18 Programming Fundamentals with Swift” (2025), @Published adalah wrapper yang nyaman di atas pola willSet, yang secara otomatis memanggil objectWillChange.send(). Sebenarnya, compiler menguraikan @Published menjadi properti terkomputasi dengan observer willSet, yang memberikan overhead nol saat runtime dibandingkan dengan implementasi manual.
Gunakan @Published untuk semua properti ObservableObject yang perubahannya harus tercermin di antarmuka. Untuk properti yang tidak memengaruhi UI, stored properties biasa tanpa @Published mengurangi jumlah penggambaran ulang yang tidak perlu.
@Published menghasilkan dua elemen kunci selama kompilasi. Pertama — properti tersimpan dengan observer willSet yang memanggil objectWillChange.send() sebelum menulis nilai baru. Kedua — proyeksi $propertyName yang mengembalikan Published.Publisher yang dapat digunakan langsung di pipeline Combine.
Pertimbangkan kelas Settings dengan tiga properti: dua @Published dan satu biasa:
class Settings: ObservableObject {
@Published var username: String = "Guest"
@Published var isDarkMode = false
var lastLogin: Date = Date() // tanpa @Published
}
Saat username atau isDarkMode berubah, SwiftUI menggambar ulang semua view yang berlangganan ke instance Settings. Perubahan lastLogin tidak akan memicu penggambaran ulang. Jika Anda perlu memberi tahu pelanggan secara manual tentang perubahan properti biasa, Anda dapat memanggil objectWillChange.send() di observer willSet.
Detail penting: @Published hanya memublikasikan perubahan saat penulisan langsung ke properti. Jika properti adalah tipe referensi (kelas) dan status internalnya berubah tanpa mengganti referensi, @Published tidak akan mendeteksinya. Dalam kasus seperti itu, diperlukan pengiriman peristiwa manual atau penggantian dengan tipe nilai (struct).
@Published terintegrasi erat dengan Combine — setiap properti @Published secara otomatis menyediakan publisher yang dapat diakses melalui proyeksi $propertyName. Ini memungkinkan penerapan operator Combine untuk pemfilteran, transformasi, penggabungan, dan pemrosesan nilai yang ditunda.
Skenario umum — pencarian dengan debounce. Bidang input terikat ke properti @Published searchText, tetapi permintaan ke server harus dikirim hanya setelah jeda 300 ms. Combine dengan $searchText.debounce menyelesaikannya dalam satu baris:
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) { }
}
Menurut artikel John Sundell (Swift by Sundell, 2024), menggabungkan @Published dengan Combine adalah pola standar untuk pipeline reaktif di aplikasi SwiftUI: validation, debounce, throttle, combineLatest, merge dengan publisher lain. @Published bertindak sebagai jembatan antara kode UI imperatif dan Combine reaktif.
Dengan dirilisnya iOS 17, Apple memperkenalkan makro @Observable, yang menawarkan pendekatan alternatif untuk reaktivitas tanpa ObservableObject dan @Published. @Observable secara otomatis melacak akses ke properti pada level pembacaan, bukan penulisan, yang memberikan penggambaran ulang yang lebih tepat — hanya view yang membaca properti yang diubah tertentu yang diperbarui.
Namun ini tidak berarti @Published sudah usang. @Published tetap diperlukan ketika integrasi dengan pipeline Combine dibutuhkan — proyeksi $propertyName memberikan publisher yang tidak dimiliki @Observable. Selain itu, untuk kompatibilitas mundur dengan iOS 16 dan yang lebih lama, @Published+ObservableObject adalah satu-satunya pilihan. Menurut sesi Apple WWDC 2023 „Discover Observation in SwiftUI”, Apple merekomendasikan @Observable untuk proyek baru, tetapi secara eksplisit mempertahankan dukungan untuk @Published untuk kode yang ada dan skenario Combine.
Dalam praktiknya, banyak proyek menggunakan pendekatan hibrida: model data baru ditulis dengan @Observable, sementara ObservableObject yang ada dengan @Published tetap tanpa refactoring. @Published juga tak tergantikan ketika kontrol yang tepat atas publikasi diperlukan — misalnya, menunda notifikasi hingga selesainya pembaruan batch beberapa properti.
Kesalahan pertama — menerapkan @Published di struct. Compiler akan menampilkan kesalahan: „Property wrapper cannot be applied to a computed property” atau „'@Published' is only available on members of a class”. @Published memerlukan semantik referensi, karena ObservableObjectPublisher adalah kelas yang harus unik untuk setiap instance.
Kesalahan kedua — mutasi konten properti referensi tanpa mengganti referensi. Jika properti @Published bertipe array [String] dan Anda memanggil array.append("new"), @Published tidak akan mendeteksi perubahan karena referensi ke array tidak berubah. Solusi: tetapkan nilai baru ke properti array = array + ["new"] atau gunakan objectWillChange.send() secara manual.
Kesalahan ketiga — jumlah properti @Published yang berlebihan. Setiap properti @Published memicu penggambaran ulang semua view yang berlangganan ke ObservableObject, bukan hanya yang membaca properti ini. Menurut Point-Free (2025), membagi satu ObservableObject besar menjadi beberapa yang lebih kecil dengan @StateObject dan @EnvironmentObject mengurangi jumlah penggambaran ulang yang tidak perlu dan meningkatkan kinerja.
Contoh pertama — ViewModel formulir pendaftaran dengan validasi. Properti @Published email dan password memicu tampilan kesalahan validasi melalui pipeline Combine:
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)
}
}
Contoh kedua — publikasi manual untuk koleksi elemen referensi. Alih-alih mengganti seluruh array pada setiap perubahan di dalam elemen, digunakan objectWillChange.send():
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() // pemberitahuan manual
}
}
Contoh ketiga — Assign ke properti @Published melalui Combine. Menggunakan sintaks baru Swift 5.9, dapat ditetapkan secara langsung melalui proyeksi assign(to: &$property) tanpa pembungkus Optional. Ini adalah cara terpendek untuk menghubungkan publisher ke properti @Published tanpa membuat langganan.
Pertanyaan yang Sering Diajukan
Tidak, @Published hanya dapat diterapkan di dalam kelas yang sesuai dengan ObservableObject. Di struct, gunakan @State untuk status lokal atau @Bindable dengan makro @Observable di iOS 17+. Mencoba menerapkan @Published di struct akan menyebabkan kesalahan kompilasi.
Benar: tetapkan nilai baru secara keseluruhan (array = array + ["new"]). @Published melacak penggantian referensi, bukan mutasi konten. Untuk koleksi tipe referensi, gunakan panggilan manual objectWillChange.send() setelah mutasi status internal elemen.
@State ditujukan untuk status lokal dalam satu view dan hanya bekerja dengan tipe nilai. @Published — untuk properti ObservableObject yang dapat dibaca oleh banyak view melalui @ObservedObject atau @EnvironmentObject. @State lebih sederhana, @Published lebih kuat berkat integrasi dengan Combine.
Hanya untuk yang perubahannya harus memperbarui UI. Properti untuk perhitungan internal, cache, atau flag sementara tidak memerlukan @Published — ini mengurangi jumlah penggambaran ulang yang tidak perlu. Gunakan @Published sebagai sinyal „properti ini penting untuk antarmuka”.
SwiftUI terintegrasi dengan Core Data melalui @FetchRequest dan @ObservedObject untuk NSManagedObject. ManagedObject sudah sesuai dengan ObservableObject, jadi @Published tidak diperlukan — NSManagedObject sendiri memberi tahu tentang perubahan. @Published digunakan di lapisan ViewModel antara Core Data dan UI untuk transformasi data.
Kesimpulan
objectWillChange.send(), menghasilkan publisher melalui proyeksi $propertyassign(to: &$property) di Swift 5.9 memungkinkan berlangganan publisher langsung ke properti @PublishedKami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga