WWDC.ai

Create high quality images using Image Playground

Use ImagePlayground.framework to present Apple's image creation UI, seed it with app context, configure style and size, and handle availability.

Watch on Apple Developer

TL;DR

  • Image Playground now uses higher-quality generative models on Private Cloud Compute, supporting many styles including photorealistic, multiple aspect ratios, people, and personalization.
  • Adoption is UI-driven: SwiftUI uses .imagePlaygroundSheet, while UIKit/AppKit use ImagePlaygroundViewController; ImageCreator is deprecated.
  • Seed generation with ImagePlaygroundConcept values from text, extracted long-form content, source images, or PencilKit drawings, then save the temporary result URL your app receives.
  • Configure ImagePlaygroundOptions for size and personalization, constrain or default styles with imagePlaygroundGenerationStyle, and gate UI with supportsImageGeneration.

What Image Playground provides

ImagePlayground.framework brings the Image Playground creation experience into iOS, iPadOS, macOS, and visionOS apps on devices with Apple Intelligence support. The experience includes prompt entry, style selection, people/personalization features, previewing, and user confirmation.

The model can generate images from short or detailed descriptions, include one or more people, use preset or text-described styles, and target landscape, portrait, or square use cases. Generation runs on Private Cloud Compute; Apple handles the server-side model infrastructure and user usage limits.

  • Supports high-quality images in many styles, including photorealistic results.
  • Preset styles discussed include animation, illustration, sketch, and emoji/Genmoji-oriented output.
  • The requested size is mapped to the closest supported resolution and aspect ratio.
  • ImageCreator, the previous non-UI image generation API, is deprecated in favor of the new Image Playground experience.

Present the Image Playground UI

In SwiftUI, adoption starts with the .imagePlaygroundSheet view modifier. The sheet is controlled by a binding and calls a completion handler with a file URL when the user accepts a generated image.

The returned URL points to a temporary location inside the app container, so apps should copy or persist the generated image before the session ends. Image Playground owns the UI, model interaction, style picker, and preview flow.

  • No SDK initialization, API keys, server endpoints, or entitlements are described for basic adoption.
  • The sheet can start empty or be prefilled with app-provided context.
  • UIKit and AppKit apps can present ImagePlaygroundViewController and receive the result through its delegate.

SwiftUI sheet adoption

Attach .imagePlaygroundSheet to a view, toggle presentation with state, and save the generated temporary file URL in the completion handler.

@State private var showingPlayground = false

var body: some View {
    Button("Create image") {
        showingPlayground = true
    }
    .imagePlaygroundSheet(
        isPresented: $showingPlayground,
        onCompletion: { url in
            var updated = currentCard
            store.saveImage(url, for: &updated)
        }
    )
}

UIKit/AppKit presentation

Use ImagePlaygroundViewController for UIKit or AppKit-style integration and handle generated image URLs through the delegate.

func presentViewController() {
    let viewController = ImagePlaygroundViewController()
    viewController.concepts = [
        .text(card.theme),
        .extracted(from: card.message)
    ]
    viewController.delegate = self
    present(viewController, animated: true)
}

func imagePlaygroundViewController(
    _ viewController: ImagePlaygroundViewController,
    didCreateImageAt url: URL
) {
    var updated = card
    store.saveImage(url, for: &updated)
    dismiss(animated: true)
}

Seed generation with app context

ImagePlaygroundConcept lets an app prime the sheet with relevant information so the user does not start from a blank prompt. Direct text can represent a concise theme, while extracted text lets the system pull the most relevant concepts from longer content such as a message.

The sheet can also take a SwiftUI Image as a source image and can include a PKDrawing from PencilKit as a visual suggestion. These inputs guide the composition but do not lock the result; users can replace or refine them in the sheet.

  • Use .text(...) for direct descriptions such as a card theme.
  • Use .extracted(from:title:) or .extracted(from:) for longer prose where the system should infer useful concepts.
  • Pass sourceImage: to provide a reference photo or existing image.
  • Append .drawing(PKDrawing) to concepts when strokes should guide generation.

Text and extracted concepts

Seed the prompt with both an explicit theme and concepts extracted from longer app content.

var concepts: [ImagePlaygroundConcept] {
    [
        .text(card.theme),
        .extracted(from: card.message, title: card.theme)
    ]
}

var body: some View {
    Button("Create image") {
        showingPlayground = true
    }
    .imagePlaygroundSheet(
        isPresented: $showingPlayground,
        concepts: concepts,
        onCompletion: { url in
            var updated = card
            store.saveImage(url, for: &updated)
        }
    )
}

PencilKit drawing as a concept

Include a non-empty PKDrawing so the model can use the user's strokes as visual guidance.

@State private var drawing = PKDrawing()

var concepts: [ImagePlaygroundConcept] {
    var result: [ImagePlaygroundConcept] = [
        .text(card.theme),
        .extracted(from: card.message)
    ]

    if !drawing.strokes.isEmpty {
        result.append(.drawing(drawing))
    }

    return result
}

Configure size, style, external providers, and personalization

ImagePlaygroundOptions configures sheet behavior such as size and personalization. For size, the app can request the closest supported output to a CGSize, allowing the same code path to adapt to landscape cards, portrait cards, square thumbnails, banners, or wallpapers.

Generation style can be defaulted and constrained. Passing a single allowed style locks the picker to that style; passing multiple styles lets the picker reflect the current app context. The externalProvider style is opt-in and surfaces a third-party provider the user has configured in Settings, such as ChatGPT, with setup handled by the system when needed.

  • Use options.sizeSpecification = .closest(to: size) to request the nearest supported aspect ratio and resolution.
  • Use .imagePlaygroundGenerationStyle(defaultStyle, in: allowedStyles) to control the default and allowed style set.
  • Use .externalProvider only by adding it to the allowed styles list.
  • Set options.personalization = .disabled when people-based personalization does not fit the app context.

Size and style configuration

Request an output size derived from app state, provide options to the sheet, and allow app-specific styles plus an external provider.

var options: ImagePlaygroundOptions {
    var options = ImagePlaygroundOptions()
    options.sizeSpecification = .closest(to: card.format.size)
    return options
}

var body: some View {
    Button("Create image") {
        showingPlayground = true
    }
    .imagePlaygroundSheet(
        isPresented: $showingPlayground,
        concepts: concepts,
        onCompletion: { url in
            var updated = card
            store.saveImage(url, for: &updated)
        }
    )
    .imagePlaygroundOptions(options)
    .imagePlaygroundGenerationStyle(
        pendingStylePreset.defaultStyle,
        in: pendingStylePreset.allowedStyles + [.externalProvider]
    )
}

Disable personalization

Remove people picker and name-detection features when personalization is not appropriate.

var options: ImagePlaygroundOptions {
    var options = ImagePlaygroundOptions()
    options.sizeSpecification = .closest(to: card.format.size)
    options.personalization = .disabled
    return options
}

Emoji-style output and availability fallback

When ImagePlaygroundStyle.emoji is active, the sheet can call onAdaptiveImageGlyphCreation with an NSAdaptiveImageGlyph instead of returning a generated image URL. Adaptive image glyphs can be embedded inline with text, like emoji, which makes them useful for small expressive icons such as recipient thumbnails.

Apps should use the supportsImageGeneration environment value to decide whether to show the full Image Playground path or a fallback. It is true only when image generation is fully available: device capability, supported language and region, and the user's Settings state are all satisfied.

  • Use .emoji when the output should be an adaptive glyph rather than regular artwork.
  • Save the NSAdaptiveImageGlyph through the glyph-specific completion path.
  • Provide a non-generation fallback, such as a Photos picker, when supportsImageGeneration is false.
  • Do not build custom usage-limit UI; the system manages Image Playground usage limits for users.

Create an adaptive image glyph

Lock the sheet to emoji style and handle NSAdaptiveImageGlyph output for inline expressive icons.

@State private var showingIconPlayground = false

var body: some View {
    Button("Create icon") {
        showingIconPlayground = true
    }

    Color.clear
        .imagePlaygroundSheet(
            isPresented: $showingIconPlayground,
            concepts: concepts,
            onCompletion: { _ in },
            onAdaptiveImageGlyphCreation: { glyph in
                var updatedCard = card
                store.saveIcon(glyph, for: &updatedCard)
            }
        )
        .imagePlaygroundGenerationStyle(.emoji, in: [.emoji])
}

Check image generation support

Branch to the Image Playground experience only when image generation is fully available, otherwise show a fallback UI.

@Environment(\.supportsImageGeneration) private var supportsImageGeneration

var body: some View {
    NavigationLink(card.recipient) {
        if supportsImageGeneration {
            CardEditorView(card: card)
        } else {
            CardPickerView(card: card)
        }
    }
}
Unofficial, not associated with Apple. BySuperwall

On this page

Ask AI