Your First visionOS App

Very basic setup for your very fist visionOS App

Siamak (Ash) Ashrafi
4 min readAug 24, 2023

Start Xcode

Need XCode Version 15 Beta

And set a visionOS app

Make visionOS App

Setup your new project

Setup the ‘FastCar’ App

Find a place to put it …

Save the project

We get this file structure with FastCarApp being the start of the App.

File structure of new visionOS App

Models

Under `Packages` we can see the models:

  • Immersive
  • Scene

‘Immersive’ is used in the Immersive view and the other (‘Scene’) is used in our current scene.

Looking at our model ‘Scene’ in XCode

Lets add a car from Apple models.

Lets get the car

download the car model

Add the toy_car (drag from downloads) to the RealityKitContent.

toy_car in XCode

FastCarApp

This is the start of the code. We are not in ImmersiveSpace so we are just calling the `ContentView()`.

import SwiftUI
@main
struct FastCarApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}.windowStyle(.volumetric)
ImmersiveSpace(id: "ImmersiveSpace") {
ImmersiveView()
}
}
}

We are not moving into an immersive view yet so we are not using the ImmersiveView.swift file.

import SwiftUI
import RealityKit
import RealityKitContent

struct ImmersiveView: View {
var body: some View {
RealityView { content in
// Add the initial RealityKit content
if let scene = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
content.add(scene)
}
}
}
}

#Preview {
ImmersiveView()
.previewLayout(.sizeThatFits)
}

If we tap the `Show ImmersiveSpace` Toggle this will call the ImmersiveView.swift file and show that model in our space.

VStack {
Toggle("Enlarge RealityView Content", isOn: $enlarge)
.toggleStyle(.button)

Toggle("Show ImmersiveSpace", isOn: $showImmersiveSpace)
.toggleStyle(.button)
}.padding().glassBackgroundEffect()

Now we replace the sphere with the car.

Open `ContentView` and look at the code …

var body: some View {
VStack {
RealityView { content in
// Add the initial RealityKit content
if let scene = try? await Entity(named: "Scene", in: realityKitContentBundle) {
content.add(scene)
}
} update: { content in
// Update the RealityKit content when SwiftUI state changes
if let scene = content.entities.first {
let uniformScale: Float = enlarge ? 1.4 : 1.0
scene.transform.scale = [uniformScale, uniformScale, uniformScale]
}
}
.gesture(TapGesture().targetedToAnyEntity().onEnded { _ in
enlarge.toggle()
})

That “Scene” is the ball from above and we want to replace it with the “toy_car”. Make sure you spell it exactly as its spelled in the project navigator.

if let scene = try? await Entity(named: "toy_car", in: realityKitContentBundle) {
content.add(scene)
}

It’s too large so we will change the scaling.

if let scene = content.entities.first {
let uniformScale: Float = enlarge ? 0.03 : 0.02
scene.transform.scale = [uniformScale, uniformScale, uniformScale]
}

Looks great :-)

“Toy Car” in visionOS simulator

--

--