# Build the SwiftUI clothing classifier

- **Lesson ID:** 05
- **Goal:** Let a user pick or view a sample image, prepare it, run Core AI, and show the top clothing label.
- **Human lesson:** [05-swiftui-clothing-app.html](05-swiftui-clothing-app.html)

## Prerequisites

- An Xcode target with the checked model/function from lesson 04.
- SwiftUI, PhotosPicker, UIKit/CoreGraphics, and Core AI imports available.

## Inputs, outputs, and artifacts

- **Inputs:** Picked `PhotosPickerItem` or bundled `fashion-sample`; `clothing.aimodel`.
- **Outputs:** Preview image, top label, confidence, and a path you can run again.
- **Artifacts:** SwiftUI `ContentView`, `ClothingClassifier`, image-prep helpers, bundled sample asset.

## Agent build steps

1. Define labels in exact order: `T-shirt/top`, `Trouser`, `Pullover`, `Dress`, `Coat`, `Sandal`, `Shirt`, `Sneaker`, `Bag`, `Ankle boot`.
2. Create an observable classifier with `result`, `confidence`, `ready`, and a stored Core AI inference function.
3. In `.task`/setup, load or specialise the bundled model, load `main`, and mark the classifier ready. Do this once.
4. On a picked or bundled `CGImage`, draw into a 28×28 one-channel grayscale buffer, scale each byte by `1/255`, and make float32 NDArray shape `[1,1,28,28]`.
5. Run using `inputs: ["image": input]`, read float32 `logits`, apply numerically stable softmax or argmax, and map the best index to the labels.
6. Build a `ContentView` with `PhotosPicker`, preview, label, percentage confidence, and disabled picker until ready. Add `fashion-sample` for an offline first run.
7. Test a sample first, then a normal photo. Keep crop/contrast/inversion experiments after the basic path works.

## Constraints

Mac/iOS Core AI only, no CUDA and no Core ML. Keep float32 0–1 grayscale and `[1,1,28,28]`; use `image`/`logits`; prepare once. Photos may not match Fashion-MNIST's dark background. Do not treat low real-photo accuracy as a tensor-contract failure until you have checked image prep.

## Key concepts

- `ClothingClassifier` prepares in `.task` and classifies when a photo or bundled sample arrives.
- Labels stay in the fixed Fashion-MNIST order. Softmax on logits is for display confidence only.
- Draw the image to 28x28 grayscale, scale bytes to 0-1, and send key `image`.
- Reuse the loaded function `main` for every image after prepare once.

## Takeaways

- Model load and specialisation never run inside the picker `onChange` handler.
- The top label comes from argmax or the softmax index into the ten-label array.
- Real photos may need crop or contrast after the basic path works.

## Acceptance checks

- The app builds and shows the bundled sample without network access.
- A picked image reaches the same image prep and inference function.
- The top label comes from the fixed ten-label array and confidence is derived from logits.
- No model loading/specialisation occurs inside the picker callback.
- Proceed to [profiling](06-profile-in-xcode.llms.md).

## Environment setup

Use Xcode 27 on macOS. Create an iOS or macOS SwiftUI App target, add the exported `.aimodel` to the target's model/resources build phase, add the **Core AI** framework under Frameworks, Libraries, and Embedded Content, and install the **Metal Toolchain** in Xcode Settings > Components. Confirm the installed toolchain with:

```bash
xcode-select --install
xcodebuild -version
```

Build the bundled model once before you add UI. Core AI and `NDArray` names can change between SDK versions, so check the exact names in the Xcode docs you have installed.
