← All courses ← Course home

Lesson 03 of 07

Treat Core AI as the program that runs the model

AIModel, InferenceFunction, and NDArray are the host contract (the agreement) around the compiled graph. Prepare once, then feed it the shape the chip expects.

Agent brief (llms.md)

Environment setup

Use Xcode 27 (the SDK version this course uses) on macOS. Create an iOS or macOS SwiftUI app target, add the target's deployment settings, and drag the exported .aimodel into the target's model/resources build phase. In Xcode, add the Core AI framework to the target's Frameworks, Libraries, and Embedded Content, and install the Metal Toolchain from Xcode Settings > Components.

xcode-select --install
xcodebuild -version
# In Xcode: File > New > Project > App, Interface: SwiftUI
# Add CoreAI to the target and add the .aimodel to Copy Bundle Resources.
# Xcode Settings > Components > install Metal Toolchain.

Build once with the bundled model before you add image or chat UI. Core AI and NDArray names can change with the SDK version, so check the exact names in the installed Xcode docs. Do not copy an API name you have not checked.

Metal can run an operation, but an app needs a host: a program that loads a graph, chooses its function, prepares resources, and passes buffers. Core AI is that host. In the original course, the Xcode lesson shows the API. Here, start from the lower requirement: a prepared function you can call must receive and return exactly the tensors described by clothing.aimodel.

Read the model file as a contract

Assetclothing.aimodel
Functionmain
Inputimage [1,1,28,28]
Outputlogits [1,10]

AIModel owns the loaded model file. Its main function is represented by an InferenceFunction. An NDArray carries the typed, shaped data for the call. Names and setup details can change with the SDK version, so use the model viewer and the installed Xcode 27 beta docs for exact Swift names.

// Shape-first pseudocode. Confirm the exact Core AI SDK calls in Xcode.
let model = try AIModel(contentsOf: clothingURL)
let main = try model.function(named: "main")
let image = NDArray(float32: pixels, shape: [1, 1, 28, 28])
let logits = try main.infer(["image": image])
// logits is [1, 10]; softmax and label mapping are display work.

The code is a shape sketch, not a claim about one exact SDK spelling. The rule that stays the same is what matters: load clothing.aimodel, get main, pass image, read logits.

Preparation is not something a tap should do

App startLoad model
App startSpecialise / prepare
Every imageReuse main

Load and prepare in app setup, or in a task that runs once. A PhotosPicker callback should make a tensor and call the function that is already prepared. Reloading on every tap breaks the profiling idea from lesson 02. It also wastes the work that makes repeated inference useful.

What the runtime must give Metal

The next layer is the UI. SwiftUI does not own the model. It must give Core AI one valid array. Continue to SwiftUI as a thin helper, or revisit the original course's clothing app lesson.

Key concepts

  • AIModel loads the file. InferenceFunction is main. NDArray carries typed shaped data.
  • The contract is clothing.aimodel to main to image [1, 1, 28, 28] to logits [1, 10].
  • Load and prepare once at app start. Every image reuses the prepared function.
  • Softmax and label mapping are display work after logits.

Takeaways

  • A picker callback should build a tensor and call an already prepared function.
  • Exact Swift names can change with the SDK. The shape contract does not.
  • The runtime must turn array descriptions into buffers with the right type and layout.