swiftship/internal/skills/data/always-visionos/visionos-patterns/SKILL.md
visionOS platform patterns: scene types, RealityKit, spatial gestures, hand tracking, entity interaction. Use when building visionOS-specific features, handling spatial input, or implementing Vision Pro app patterns. Triggers: visionOS, Vision Pro, RealityKit, spatial, immersive, hand tracking, eye tracking.
npx skillsauth add abdullah4ai/apple-developer-toolkit visionos-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
import RealityKit
// In a RealityView
RealityView { content in
if let entity = try? await Entity(named: "Scene", in: realityKitContentBundle) {
// Add collision and input for interaction
entity.components.set(CollisionComponent(shapes: [.generateBox(size: [0.1, 0.1, 0.1])]))
entity.components.set(InputTargetComponent())
content.add(entity)
}
}
Entities need CollisionComponent + InputTargetComponent for user interaction:
RealityView { content in
let sphere = ModelEntity(mesh: .generateSphere(radius: 0.1))
sphere.components.set(CollisionComponent(shapes: [.generateSphere(radius: 0.1)]))
sphere.components.set(InputTargetComponent())
content.add(sphere)
} update: { content in
// Update entities
}
.gesture(
TapGesture()
.targetedToAnyEntity()
.onEnded { value in
// Handle tap on entity
}
)
// Tap gesture on entities
.gesture(
TapGesture()
.targetedToAnyEntity()
.onEnded { value in
handleTap(on: value.entity)
}
)
// Drag gesture on entities
.gesture(
DragGesture()
.targetedToAnyEntity()
.onChanged { value in
value.entity.position = value.convert(value.location3D, from: .local, to: .scene)
}
)
ARKit is only available in Full Space (not Shared Space):
ImmersiveSpace(id: "full-immersive") {
RealityView { content in
// ARKit features available here
}
}
.immersionStyle(selection: .constant(.full), in: .full)
Use @Observable over ObservableObject:
@Observable
class AppModel {
var items: [Item] = []
var selectedItem: Item?
var isImmersive = false
}
// In App
@State private var model = AppModel()
WindowGroup {
ContentView()
.environment(model)
}
MainActor by default in Swift 6.2. Use detached Tasks for background work:
// Already on MainActor by default
func loadData() {
Task.detached {
let data = await fetchData()
await MainActor.run {
self.items = data
}
}
}
Eye tracking drives hover states automatically:
Button("Action") { }
.hoverEffect() // Required for all interactive elements
.hoverEffect(.highlight) // Highlight variant
.hoverEffect(.lift) // Lift variant
visionOS 26 widgets are spatial — they snap to walls and tables:
// Standard WidgetKit implementation works
// visionOS renders them as spatial glass panels
.foregroundStyle() not .foregroundColor().clipShape(.rect(cornerRadius:)) not .cornerRadius()@Observable not ObservableObjectUIScreen.mainCollisionComponent + InputTargetComponent for interaction@Observable over ObservableObject.hoverEffect().targetedToAnyEntity()) for 3D interactionTask.detached for background work.foregroundStyle() not .foregroundColor().clipShape(.rect(cornerRadius:)) not .cornerRadius()testing
Use for 3D games: racing, 3D sports, board games, marble maze, tower defense, bowling. SceneKit + SceneView architecture, 3D scene hierarchy, physics, game loop, primitives, materials, cameras, particles, audio.
documentation
Game UI patterns: SwiftUI HUD overlays on SpriteKit, menus (main/pause/game-over), virtual joystick/d-pad, score displays, health bars, tutorial onboarding.
tools
Download free game sprites/textures/3D models and generate procedural assets. Covers nw_download_asset tool, texture factories, sprite atlas organization, 3D model loading, and programmatic asset creation.
testing
Use for 2D games: arcade, puzzle, sports, ping pong, platformer, shooter, 2D racing. SpriteKit + SpriteView architecture, scene hierarchy, physics, game loop, audio, particles, game feel.