Search Docs
Loading...
Skip to content

Architecture

Understand how CE.SDK is structured around the CreativeEngine and its six interconnected APIs.

5 mins
estimated time
GitHub

CE.SDK is built around the CreativeEngine—a single-threaded core runtime that manages state, rendering, and coordination between six specialized APIs. Understanding how these pieces connect helps you navigate the SDK effectively.

The CreativeEngine#

The Engine is the central coordinator. All operations—creating content, manipulating blocks, rendering, and exporting—flow through it. Initialize it once and access everything else through its API namespaces.

The Engine manages:

  • One active scene containing all design content
  • Six API namespaces for different domains of functionality
  • Event dispatching for reactive state management
  • Resource loading and caching
  • Rendering to a Metal view or offscreen context

All engine operations run on the main thread. In Swift, this is enforced by marking the Engine class as @MainActor.

Core APIs#

The engine exposes six API namespaces, each handling a specific domain of functionality:

// The engine exposes six API namespaces:
_ = engine.scene // Scene API — content hierarchy
_ = engine.block // Block API — create and modify blocks
_ = engine.asset // Asset API — manage asset sources
_ = engine.editor // Editor API — edit modes, undo/redo, roles
_ = engine.event // Event API — subscribe to changes
_ = engine.variable // Variable API — template variables
APINamespacePurpose
Scene APIengine.sceneContent hierarchy—create, load, save scenes
Block APIengine.blockCreate, modify, and query design blocks
Asset APIengine.assetRegister and query asset sources
Editor APIengine.editorEdit modes, undo/redo, user roles
Event APIengine.eventSubscribe to engine state changes
Variable APIengine.variableTemplate variables for data-driven designs

Content Hierarchy#

CE.SDK organizes content in a tree: ScenePagesBlocks.

  • Scene: The root container. One scene per engine instance. Operates in either Design Mode (static) or Video Mode (timeline-based).
  • Pages: Containers within a scene. Artboards in Design Mode, timeline compositions in Video Mode.
  • Blocks: The atomic units—graphics, text, audio, video. Everything visible is a block.

Create a scene, add a page, and populate it with blocks:

// Create a scene with a page and a graphic block.
let scene = try engine.scene.create()
let page = try engine.block.create(.page)
try engine.block.appendChild(to: scene, child: page)
let block = try engine.block.create(.graphic)
try engine.block.setShape(block, shape: engine.block.createShape(.rect))
try engine.block.setFill(block, fill: engine.block.createFill(.color))
try engine.block.appendChild(to: page, child: block)
// Traverse the hierarchy.
let pages = try engine.scene.getPages()
let children = try engine.block.getChildren(pages.first!)

The Scene API manages this hierarchy. The Block API manipulates individual blocks within it. See Scenes and Blocks for details.

Scene Modes#

CE.SDK supports two scene modes that determine available features and behavior:

// Design mode — static designs like social posts and print materials.
let designScene = try engine.scene.create()
// Video mode — time-based content with playback and timeline.
let videoScene = try engine.scene.createVideo()
  • Design Mode: Static designs—social posts, print materials, graphics. Blocks are positioned spatially on pages. Created with engine.scene.create().
  • Video Mode: Time-based content with playback, timeline, and audio support. Blocks have temporal properties like duration and trim. Created with engine.scene.createVideo().

Choose the mode when creating a scene. It determines which Block API properties and Editor API capabilities are available. See Scenes for details.

Event System#

Subscribe to engine events to build reactive UIs that update when state changes. The Event API provides Swift-native AsyncStream for consuming events:

// Subscribe to block changes using AsyncStream.
let subscription = engine.event.subscribe(to: [scene])
Task {
for await events in subscription {
for event in events {
print("Block \(event.block) had event: \(event.type)")
}
}
}

Store your Task and cancel it when you no longer need updates to prevent leaks.

See Events for details on subscribing to engine state changes.

Template Variables#

The Variable API enables data-driven designs. Define variables at the scene level and reference them in text blocks with {{variableName}} syntax:

// Set and retrieve template variables.
try engine.variable.set(key: "username", value: "Jane")
let username = try engine.variable.get(key: "username")

When variable values change, affected blocks update automatically.

How They Connect#

A typical flow shows the interconnection:

  1. Scene API creates the content structure
  2. Asset API provides images, templates, or other content
  3. Block API creates blocks and applies assets to them
  4. Variable API injects dynamic data into text blocks
  5. Editor API controls what users can modify
  6. Event API notifies your UI of every change

Each API focuses on one domain but works through the others. The Engine coordinates these interactions.

Integration Patterns#

CE.SDK runs in two contexts on Apple platforms, determined by the render context you choose at initialization:

  • Interactive: Pass a Metal view as the render context. The engine renders content on screen in real time. Use with the built-in editor UI (IMGLYEditor) for a full editing experience, or build your own SwiftUI interface on top of the engine APIs for complete control.
  • Headless: Initialize with an .offscreen render context—no view required. Use for server-side exports, automation, and batch operations where you need to process designs without displaying them.

Both patterns use the same six APIs—only rendering differs.

Next Steps#

  • Scenes — Scene creation and management
  • Blocks — Working with design blocks