Skip to content

Load a Scene

Loading an existing scene allows resuming work on a previous session or adapting an existing template to your needs.

Load Scenes from a Remote URL

Determine a URL that points to a scene binary string.

let sceneUrl =
URL(string: "https://cdn.img.ly/assets/demo/v1/ly.img.template/templates/cesdk_postcard_1.scene")!

We can then pass that string to the func load(from url: URL) async throws -> DesignBlockID function. The editor will reset and present the given scene to the user. The function is asynchronous and it does not throw if the scene load succeeded.

let scene = try await engine.scene.load(from: sceneUrl)

From this point on we can continue to modify our scene. In this example, assuming the scene contains a text element, we add a drop shadow to it. See Modifying Scenes for more details.

let text = try engine.block.find(byType: .text).first!
try engine.block.setDropShadowEnabled(text, enabled: true)

Scene loads may be reverted using engine.editor.undo().

To later save your scene, see Saving Scenes.

Full Code

Here’s the full code:

import Foundation
import IMGLYEngine
@MainActor
func loadSceneFromRemote(engine: Engine) async throws {
let sceneUrl =
URL(string: "https://cdn.img.ly/assets/demo/v1/ly.img.template/templates/cesdk_postcard_1.scene")!
let scene = try await engine.scene.load(from: sceneUrl)
let text = try engine.block.find(byType: .text).first!
try engine.block.setDropShadowEnabled(text, enabled: true)
}

Load Scenes from a String

In this example, we fetch a scene from a remote URL and load it as a string. This string could also come from the result of func saveToString() async throws -> String.

let sceneURL =
URL(string: "https://cdn.img.ly/assets/demo/v1/ly.img.template/templates/cesdk_postcard_1.scene")!
let sceneBlob = try await URLSession.shared.data(from: sceneURL).0
let blobString = String(data: sceneBlob, encoding: .utf8)!

We can pass that string to the func load(from string: String) async throws -> DesignBlockID function. The editor will then reset and present the given scene to the user. The function is asynchronous and it does not throw if the scene load succeeded.

let scene = try await engine.scene.load(from: blobString)

From this point on we can continue to modify our scene. In this example, assuming the scene contains a text element, we add a drop shadow to it. See Modifying Scenes for more details.

let text = try engine.block.find(byType: .text).first!
try engine.block.setDropShadowEnabled(text, enabled: true)

Scene loads may be reverted using engine.editor.undo().

To later save your scene, see Saving Scenes.

import Foundation
import IMGLYEngine
@MainActor
func loadSceneFromString(engine: Engine) async throws {
let sceneURL =
URL(string: "https://cdn.img.ly/assets/demo/v1/ly.img.template/templates/cesdk_postcard_1.scene")!
let sceneBlob = try await URLSession.shared.data(from: sceneURL).0
let blobString = String(data: sceneBlob, encoding: .utf8)!
let scene = try await engine.scene.load(from: blobString)
let text = try engine.block.find(byType: .text).first!
try engine.block.setDropShadowEnabled(text, enabled: true)
}

Load Scenes From a Blob

In this example, we fetch a scene from a remote URL and load it as sceneBlob.

let sceneURL =
URL(string: "https://cdn.img.ly/assets/demo/v1/ly.img.template/templates/cesdk_postcard_1.scene")!
let sceneBlob = try await URLSession.shared.data(from: sceneURL).0

To acquire a scene string from sceneBlob, we need to read its contents into a string.

let blobString = String(data: sceneBlob, encoding: .utf8)!

We can then pass that string to the func load(from string: String) async throws -> DesignBlockID function. The editor will reset and present the given scene to the user. The function is asynchronous and it does not throw if the scene load succeeded.

let scene = try await engine.scene.load(from: blobString)

From this point on we can continue to modify our scene. In this example, assuming the scene contains a text element, we add a drop shadow to it. See Modifying Scenes for more details.

let text = try engine.block.find(byType: .text).first!
try engine.block.setDropShadowEnabled(text, enabled: true)

Scene loads may be reverted using engine.editor.undo().

To later save your scene, see Saving Scenes.

Full Code

Here’s the full code:

import Foundation
import IMGLYEngine
@MainActor
func loadSceneFromBlob(engine: Engine) async throws {
let sceneURL =
URL(string: "https://cdn.img.ly/assets/demo/v1/ly.img.template/templates/cesdk_postcard_1.scene")!
let sceneBlob = try await URLSession.shared.data(from: sceneURL).0
let blobString = String(data: sceneBlob, encoding: .utf8)!
let scene = try await engine.scene.load(from: blobString)
let text = try engine.block.find(byType: .text).first!
try engine.block.setDropShadowEnabled(text, enabled: true)
}

Loading Scene Archives

Loading a scene archives requires unzipping the archives contents to a location, that’s accessible to the CreativeEngine. One could for example unzip the archive via unzip archive.zip and then serve its contents using $ npx serve. This spins up a local test server, that serves everything contained in the current directory at http://localhost:3000

The archive can then be loaded by calling await engine.scene.loadFromURL('http://localhost:3000/scene.scene'). See loading scenes for more details. All asset paths in the archive are then resolved relative to the location of the scene.scene file. For an image, that would result in 'http://localhost:3000/images/1234.jpeg'. After loading all URLs are fully resolved with the location of the scene.scene file and the scene behaves like any other scene.

Resolving assets from a different source

The engine will use its URI resolver to resolve all asset paths it encounters. This allows you to redirect requests for the assets contained in archive to a different location. To do so, you can add a custom resolver, that redirects requests for assets to a different location. Assuming you store your archived scenes in a scenes/ directory, this would be an example of how to do so:

try engine.editor.setURIResolver { path in
let url = URL(string: path)!
let components = URLComponents(string: path)!
if components.host == "localhost" && components.path.hasPrefix("/scenes") && !components.path.hasSuffix(".scene") {
// Apply custom logic here, e.g. redirect to a different server
}
// Use default behaviour for everything else
return URL(string: engine.editor.defaultURIResolver(relativePath: path))!
}