WWDC Quick Look đź’“ By SwiftGGTeam
What's new in Quick Look for visionOS

What's new in Quick Look for visionOS

Watch original video

Highlight

Quick Look on visionOS adds the PreviewApplication API to open windowed previews in a few lines of code; 3D models support Surface Mapping that automatically snaps to desks, and USDZ variants let you switch multiple color schemes within a single file.


Core Content

There are two ways to preview files on visionOS: inline (as a full-screen cover over your app) and windowed (displayed in an independent volume so users can interact with your app simultaneously). But windowed preview previously could only be triggered by drag-and-drop—apps had almost no control over the preview process: no custom title, no way to disable editing, no notification when the user closed preview.

This year Apple introduced the PreviewApplication API, built on SwiftUI and Swift Concurrency. Call PreviewApplication.open with a URL to open windowed preview; pass a URL array for collection view with forward/back navigation arrows. Through PreviewItem you can customize the title (displayName) and editing mode (editingMode)—for example, .disabled removes crop, trim, and other edit buttons. The API returns a session object whose events is a Swift async stream for listening to preview open and close events.

For 3D content, two highly requested features landed. Surface Mapping lets any 3D model automatically snap to desks or floors—drag the window bar near a surface to trigger, then slide the model freely with pitch rotation locked to prevent clipping into the surface. Configurations (called variants in USDZ) let one file contain multiple variants, such as different iPhone colors—users switch directly in Quick Look without separate files per color. This works on iOS and macOS too; visionOS also supports syncing configuration changes during FaceTime calls.


Detailed Content

PreviewApplication API

Basic usage: pass a single file URL to PreviewApplication.open (02:53).

PreviewApplication.open(url: selectedURL)

Pass a URL array to open collection view (03:48):

PreviewApplication.open(urls: allURLs, selectedURL: selectedURL)

Key points:

  • urls parameter accepts an array—Quick Look shows collection view with navigation arrows
  • selectedURL specifies the initially focused file

Customize title and editing mode with PreviewItem (05:19):

let previewItem = PreviewItem(url: selectedURL, displayName: entryName, editingMode: .disabled)
PreviewApplication.open(previewItem: previewItem)

Key points:

  • displayName appears in the Quick Look top menu bar
  • editingMode: .disabled removes edit buttons, preventing accidental modification of original files
  • See API documentation for other editingMode options

Manage preview lifecycle through session events (06:47):

let session = PreviewApplication.open(url: selectedURL)
for await event in session.events {
    switch event {
    case .opened:
        isPreviewOpen = true
    case .closed:
        isPreviewOpen = false
    }
}

Key points:

  • session.events is a Swift AsyncSequence—iterate with for await
  • .opened and .closed events let you sync preview state in your UI
  • Reopening the same file doesn’t create a new window—it brings the existing one to front

USDZ Variants (Configurations)

Define configuration variants with variantSet in USDZ (12:22):

#usda 1.0
(
    defaultPrim = "iPhone"
)

def Xform "iPhone" (
    variants = {
        string Color = "Black_Titanium"
    }
    prepend variantSets = ["Color"]
)
{
    variantSet "Color" = {
        "Black_Titanium" { }
        "Blue_Titanium" { }
        "Natural_Titanium" { }
        "White_Titanium" { }
    }
}

Key points:

  • All variants must be defined on defaultPrim for Quick Look to query and display correctly
  • string Color = "Black_Titanium" sets the default variant
  • prepend variantSets = ["Color"] declares the variant set name
  • Variant names don’t support spaces—use underscores; Quick Look converts them to spaces for display
  • Configuration button appears at the bottom of Quick Look; selecting a variant reloads the model
  • Avoid heavy textures or complex geometry in variants to prevent slow loading

Surface Mapping

  • All 3D models automatically enable Surface Mapping—no extra code needed
  • Supports horizontal surfaces (desks, floors)
  • Drag the window bar near a surface to trigger snap, accompanied by a sound
  • After snapping, pitch rotation is locked to prevent the model clipping into the surface
  • When exporting USDZ, ensure the model bottom sits at the coordinate origin for correct snap behavior

Core Takeaways

  1. Use PreviewApplication.open instead of inline Quick Look: Windowed preview doesn’t interrupt the user’s current task and supports multitasking; code drops from SwiftUI fullScreenCover + UIViewControllerRepresentable to a one-line call. Call PreviewApplication.open(url:) in the thumbnail’s onTapGesture.

  2. Create USDZ files with variants: One file contains all color options—users switch in Quick Look directly, reducing file count and management overhead; FaceTime on visionOS also supports configuration sync. Define variantSet on the USDZ defaultPrim, each variant corresponding to a configuration; use underscores instead of spaces in variant names.

  3. Ensure 3D model bottom aligns with coordinate origin: Quick Look Surface Mapping is enabled by default for all models—if the bottom isn’t at the origin, the model floats or clips after snapping to a desk. Shift the model down in your 3D modeling software before export so the bottom sits on the Y=0 plane.

  4. Use session.events to mark files being previewed in your UI: After opening multiple previews, users forget which files they’re viewing—visual markers like an eye icon clearly indicate state. Store the session returned by PreviewApplication.open and update state variables in for await event in session.events to drive UI refresh.


Comments

GitHub Issues · utterances