Section 1/131 menit
1. Masalah yang Dipecahkan
1. Masalah yang Dipecahkan
Era Sebelum Observable: ObservableObject + @Published
Sebelum @Observable hadir di Swift 5.9, SwiftUI menggunakan ObservableObject dari framework Combine:
swift
// Swift 5.x — cara lama
import Combine
class UserViewModel: ObservableObject {
@Published var name: String = ""
@Published var email: String = ""
@Published var isLoading: Bool = false
var internalCache: [String: Any] = [:] // juga di-observe, padahal tidak mau
}
Masalah besar ObservableObject:
Masalah 1: Granularitas Terlalu Kasar (Over-notification)
swift
class CartViewModel: ObservableObject {
@Published var items: [CartItem] = []
@Published var totalPrice: Double = 0
@Published var couponCode: String = ""
@Published var isCheckingOut: Bool = false
}
// View A hanya menampilkan totalPrice.
// View B hanya menampilkan items.
// View C hanya menampilkan couponCode.
//
// Ketika 'isCheckingOut' berubah (tidak relevan untuk A, B, C),
// SEMUA VIEW di-invalidate dan di-render ulang.
// ObservableObject menggunakan objectWillChange publisher —
// satu sinyal untuk SEMUA perubahan property.
objectWillChange adalah all-or-nothing: satu property berubah → semua subscriber dinotifikasi → semua view yang mengobservasi object ini di-render ulang, meski properti yang mereka tampilkan tidak berubah.
Masalah 2: Ketergantungan pada Combine
ObservableObject adalah protocol dari framework Combine — bukan bagian dari Swift standard library. Ini berarti:
- Di server-side Swift (Linux), Combine tidak tersedia
- Di UIKit tanpa SwiftUI, harus import Combine hanya untuk state management
- Testing lebih kompleks karena Combine infrastructure ikut terbawa
Masalah 3: Boilerplate @Published
Setiap property yang ingin di-observe harus diberi anotasi @Published. Jika lupa — property itu tidak di-observe dan UI tidak update. Jika tidak sengaja menambahkan @Published ke property internal — property itu ikut men-trigger re-render yang tidak perlu.
Masalah 4: @EnvironmentObject Tidak Type-Safe
swift
// Lupa inject environmentObject → crash saat runtime, bukan compile error
struct SomeView: View {
@EnvironmentObject var viewModel: CartViewModel // crash jika tidak di-inject
}