Section 3/131 menit
3. Sintaks Dasar
3. Sintaks Dasar
Deklarasi
swift
import Observation
// Cukup tambahkan @Observable — tidak perlu ObservableObject, tidak perlu @Published.
// Berlaku untuk class (reference type) — struct tidak bisa @Observable karena
// struct tidak punya identity yang stable untuk observation.
@Observable
final class ProductViewModel {
// Semua stored property otomatis di-observe — tidak perlu @Published.
var products: [Product] = []
var searchQuery: String = ""
var isLoading: Bool = false
var selectedCategory: Category = .all
var errorMessage: String? = nil
// Computed property juga otomatis di-track berdasarkan stored property
// yang dibaca di dalamnya.
var filteredProducts: [Product] {
if searchQuery.isEmpty { return products }
return products.filter { $0.name.localizedCaseInsensitiveContains(searchQuery) }
}
}
Penggunaan di SwiftUI
swift
struct ProductListView: View {
// Tidak perlu @StateObject/@ObservedObject/@EnvironmentObject —
// cukup simpan sebagai stored property biasa atau gunakan @State untuk ownership.
@State private var viewModel = ProductViewModel()
var body: some View {
NavigationStack {
List(viewModel.filteredProducts) { product in // track: filteredProducts
ProductRow(product: product)
}
.searchable(text: $viewModel.searchQuery) // track: searchQuery
.overlay {
if viewModel.isLoading { // track: isLoading
ProgressView()
}
}
.task {
await viewModel.loadProducts()
}
}
}
}
// Passing ke child view — tidak perlu @ObservedObject, cukup var biasa.
// SwiftUI otomatis track property mana yang dibaca di body child view.
struct ProductRow: View {
var product: Product // nilai yang sudah di-copy — tidak di-observe langsung
var body: some View {
Text(product.name)
}
}
// Passing viewModel ke child — child menerima reference ke object yang sama.
struct ProductDetailView: View {
var viewModel: ProductViewModel // tidak perlu @ObservedObject
var body: some View {
Text(viewModel.selectedCategory.rawValue) // track: selectedCategory
}
}
Dengan @Environment (Pengganti @EnvironmentObject)
swift
// Inject via .environment() — type-safe, tidak perlu @EnvironmentObject
struct MyApp: App {
@State private var authViewModel = AuthViewModel()
var body: some Scene {
WindowGroup {
ContentView()
.environment(authViewModel) // inject sebagai environment value
}
}
}
// Konsumsi di child view
struct ProfileView: View {
@Environment(AuthViewModel.self) private var auth // type-safe, compile error jika lupa inject
var body: some View {
Text("Hello, \(auth.currentUser?.name ?? "Guest")")
}
}