Scripting a process for the Example Code Xcode Project
An update to the Example Code workspace what we use on Step Into Vision.
Background:
- Building Step Into Labs – This article describes the Xcode project structure I set up last year.
- Using Xcode File Templates for the Labs and Example Code
When working on Example Code for this website, I generally don’t want to make an entire Xcode project just to teach a simple concept. Prior to starting Step Into Vision I cobbled together a simple project structure. I’ve been using that for Example Code and Labs. I create a Swift file for each Example or Lab (separate Xcode projects). I do all the work for the example in that file. This works well for me, but the way I set up the project meant that I had to do a handful of things each time.
- Create the swift file, normally using a file template and serialized name (Example001, Example002,…)
- Update a router to add a new case to a switch statement (
case "Example 001": Example001()…) - Create a new entry in the directory. See below.
- Update file metadata at the top of the file. I normally do this at the end when adding comments and notes.
// Example struct
struct Example: Identifiable {
let id = UUID()
var type: ExampleType
var isFeatured = false
var date: Date
var title: String
var subtitle: String
var description: String
var success: Bool = true
init(title: String, type: ExampleType, date: Date, isFeatured: Bool = false, subtitle: String, description: String, success: Bool = true) {
self.title = title
self.type = type
self.isFeatured = isFeatured
self.date = date
self.subtitle = subtitle
self.description = description
self.success = success
}
}// Example Examples
class ModelData {
var exampleData: [Example] = [
Example(title: "Example 001",
type: .WINDOW,
date: Date("10/15/2024"),
isFeatured: false,
subtitle: "Open a 2D Window",
description: "Testing out the window")
,Example(title: "Example 002",
type: .VOLUME,
date: Date("10/15/2024"),
isFeatured: false,
subtitle: "Open a Volume",
description: "Testing out the volume")
,Example(title: "Example 003",
type: .SPACE,
date: Date("10/15/2024"),
isFeatured: false,
subtitle: "Open Immersive Space",
description: "Testing out the immersive space")
]
} The data that shows up in the UI lives in ModelData. The title is also used for the switch statement in the router. This process has worked well, but I’ve wanted to improve it for some time. The main issue is that at some point we actually have to use the SwiftUI file for each example. Swift won’t let us compute the name of a View at runtime. My workaround to this was the Directory (data) and Router (turning data into Views).
I’ve been tinkering on a new process that replaces (or automates) this based on the metadata in the header of each Example file.
// Step Into Vision - Example Code
//
// Title: Example132
//
// Subtitle: Spatial SwiftUI: Preferred Surroundings Effect
//
// Description: We can use this SwiftUI modifier to adjust the lighting and tint color for the passthrough feed.
//
// Type: Window
//
// Featured: true
//
// Created by Joseph Simpson on 12/8/25.A new script will read the metadata from all the Swift files in the Examples folder. It will generate a new ExampleRegistry with all the data the UI needs. The comments above becomes this:
Example(
title: "Example 132",
type: .WINDOW,
date: Date("12/8/2025"),
isFeatured: true,
subtitle: "Spatial SwiftUI: Preferred Surroundings Effect",
description: "We can use this SwiftUI modifier to adjust the lighting and tint color for the passthrough feed.",
makeView: { AnyView(Example132()) }
)Which then becomes this in the app:

The obvious downside to this process is that the data is in comments instead of code. I can live with it.
Video Tour
I recorded a short video to show this in action. This provides a bit more background, an example of changing a file, and an example of creating a new one.
You can take a look at the script. Codex did most of the work on this one. I just made a few small changes to replace depreciated features.
The updated readme contains the process to run this script from the terminal. I also worked on a new Build Phase script to run this with each build. It took some trial and error but I have it working (again, thanks to Codex).

The key here was set User Script Sandboxing to No.

The next steps will be to port this to the Xcode projects for Labs and Dark Spaces. I’d also like to make an empty Xcode project template so we can use this for other topics.
Feel free to download the entire Example Code project. Let me know if you run into issues building it with the new script.

Follow Step Into Vision