# A First Look at SwiftUI — Swift

Source: https://www.skillbyai.com/en/swift/p-swiftui

> Understand how Swift language features appear in a small SwiftUI view.

## Where the language meets the UI

**SwiftUI** is Apple's declarative UI framework. A view is a **struct** conforming to `View` with a computed `body` property returning **`some View`** (an opaque type), built with **result builders** inside containers such as `VStack`, `HStack` and `List`. State lives in **property wrappers** and observation: `@State` for simple local values, `@Binding` to share them with child views, and `@Observable` model classes (from the Observation framework) for app state, usually annotated `@MainActor`. Views are **values** that SwiftUI recreates cheaply; when state changes, SwiftUI recomputes `body` and updates only what changed on screen. Asynchronous loading uses the `.task` modifier, which is cancelled automatically when the view disappears. Previews with `#Preview` (a macro) render views live in Xcode. This course covers the language; SwiftUI layout, navigation and data flow deserve their own course, but every concept you have learned (structs, closures, generics, protocols, property wrappers, concurrency) appears in even the smallest SwiftUI screen.

## State drives the view

When state changes, SwiftUI recomputes the view description and updates the screen.

![A small state box with an arrow into a view template, which outputs a phone screen; a loop arrow returns from the screen to the state box.](assets/figures/swift/section-8-map.svg) — Figure 8.1 — The SwiftUI state and render loop.

## A small SwiftUI screen

Structs, opaque types, property wrappers, closures and async loading together.

```swift
import SwiftUI

@MainActor
@Observable
final class ProductListModel {
    var products: [Product] = []
    var isLoading = false

    func load() async {
        isLoading = true
        defer { isLoading = false }
        products = (try? await ProductAPI.fetchAll()) ?? []
    }
}

struct ProductListView: View {
    @State private var model = ProductListModel()
    @State private var searchText = ""

    private var filtered: [Product] {
        searchText.isEmpty ? model.products
                           : model.products.filter { $0.title.localizedCaseInsensitiveContains(searchText) }
    }

    var body: some View {
        NavigationStack {
            List(filtered) { product in
                VStack(alignment: .leading) {
                    Text(product.title).font(.headline)
                    Text(product.price, format: .currency(code: "INR"))
                }
            }
            .overlay { if model.isLoading { ProgressView() } }
            .searchable(text: $searchText)
            .navigationTitle("Products")
            .task { await model.load() }              // cancelled if the view disappears
        }
    }
}

#Preview { ProductListView() }
```

## Keep logic out of body

`body` may be called often. Keep it a cheap description of the UI, and put loading, validation and business rules in model types that you can unit test without SwiftUI.

**Quiz:** In SwiftUI, what does `var body: some View` use?

- [ ] An existential any View
- [ ] A class hierarchy
- [x] An opaque return type: one specific view type hidden from callers
- [ ] A property wrapper

*Answer:* An opaque return type: one specific view type hidden from callers. some View lets the compiler know the exact type while keeping it hidden and efficient.
