### Android: Custom Photo Editor Builder Source: https://context7.com/imgly/editor-react-native/llms.txt Replace the default photo editor builder with a custom Composable lambda. This example forces a specific starting image by providing a default URI. ```kotlin package com.myapp import android.app.Application import androidx.compose.runtime.Composable import androidx.core.net.toUri import ly.img.editor.Editor import ly.img.editor.configuration.photo.PhotoConfigurationBuilder import ly.img.editor.core.configuration.EditorConfiguration import ly.img.editor.core.configuration.remember import ly.img.editor.reactnative.module.IMGLYEditorModule import ly.img.editor.reactnative.module.builder.CustomBuilderScope import ly.img.editor.reactnative.module.builder.EditorBuilder import ly.img.editor.reactnative.module.builder.EditorBuilderDefaults import ly.img.editor.reactnative.module.model.EditorPreset import ly.img.editor.reactnative.module.model.EditorSourceType import ly.img.editor.configuration.photo.callback.onCreate import ly.img.editor.configuration.photo.callback.onExport class MyApplication : Application() { override fun onCreate() { super.onCreate() IMGLYEditorModule.builderClosure = { preset, metadata -> when (preset) { EditorPreset.PHOTO -> { // Custom photo editor that forces a specific starting image @Composable fun CustomBuilderScope.CustomPhoto() { Editor( license = settings.license, baseUri = settings.baseUri.toUri(), userId = settings.userId, configuration = { EditorConfiguration.remember(::PhotoConfigurationBuilder) { onCreate = { onCreate( createScene = { EditorBuilderDefaults.onCreateScene( scope = this@Editor, settings = settings, defaultUri = "https://example.com/template.jpg".toUri(), sourceType = EditorSourceType.IMAGE, ) } ) } onExport = { onExport( postExport = { val result = EditorBuilderDefaults.getExportResult( scope = this@Editor, byteBuffer = it, ) result(Result.success(result)) }, error = { result(Result.failure(it)) }, ) } } }, ) { onClose(it) } } // Return as a Builder lambda { CustomPhoto() } } else -> EditorBuilder.design() // default fallback } } } } ``` -------------------------------- ### iOS: Video Duration Constraints Source: https://context7.com/imgly/editor-react-native/llms.txt Enforces minimum and maximum video duration constraints as soon as the scene is loaded. This prevents users from interacting with a timeline that violates these constraints. The example also shows how to export as MP4. ```swift import IMGLYEditor import IMGLYEngine Editor(engineSettings) .imgly.configuration { VideoEditorConfiguration { builder in builder.onLoaded { context, existing in // Constrain all videos to 10–20 seconds context.eventHandler.send( .setVideoDurationConstraints( minimumVideoDuration: 10, maximumVideoDuration: 20, ), ) try await existing() } builder.onExport { engine, eventHandler, _ in // Export as MP4 let editorResult = try await OnExport.exportVideo(engine, eventHandler, .mp4) // handle editorResult… } } } ``` -------------------------------- ### Open Photo Editor with IMGLYEditor Source: https://context7.com/imgly/editor-react-native/llms.txt Launches a fullscreen photo editor modal. Pass a license key for production or omit for evaluation mode. The source parameter pre-loads an image. The promise resolves with editor results or null if cancelled. ```typescript import IMGLYEditor, { EditorSettingsModel, EditorPreset, SourceType, type EditorResult, } from '@imgly/editor-react-native'; async function openPhotoEditor(imageUri: string): Promise { const settings = new EditorSettingsModel({ license: 'YOUR_LICENSE_KEY', // pass undefined to run in evaluation mode userId: 'user-abc-123', // optional — used for MAU tracking // baseUri defaults to IMG.LY CDN; override to self-host assets: // baseUri: 'https://your-cdn.example.com/cesdk-assets', }); let result: EditorResult | null = null; try { result = await IMGLYEditor.openEditor( settings, { source: imageUri, type: SourceType.IMAGE }, // pre-load an image EditorPreset.PHOTO, { myCustomKey: 'myCustomValue' }, // optional metadata forwarded to native callbacks ); } catch (e) { console.error('Editor export failed:', e); return; } if (result === null) { console.log('User cancelled the editor'); return; } console.log('Exported artifact path:', result.artifact); // e.g. file:///tmp/export.png console.log('Scene path:', result.scene); // .scene file for reload console.log('Thumbnail path:', result.thumbnail); // small preview PNG console.log('Custom metadata:', result.metadata); // { [key]: unknown } } ``` -------------------------------- ### Open React Native Editor with License Source: https://github.com/imgly/editor-react-native/blob/main/README.md Import the IMGLYEditor module and open the editor with your license key. Use 'null' for the license to run in evaluation mode with a watermark. ```typescript import IMGLYEditor from '@imgly/editor-react-native'; // Configure the editor. const settings = new EditorSettingsModel({ license: "YOUR_LICENSE_KEY" }); // Open the editor and retrieve the result. const result = await IMGLYEditor.openEditor(settings); ``` -------------------------------- ### Configure Editor Settings with EditorSettingsModel Source: https://context7.com/imgly/editor-react-native/llms.txt Provides configuration for the editor runtime, including license, CDN base URI, and user ID. The baseUri defaults to the IMG.LY CDN but should be overridden for production to a self-hosted asset bundle. ```typescript import { EditorSettingsModel, type EditorSettings } from '@imgly/editor-react-native'; // Minimal — evaluation mode (watermark shown) const evalSettings = new EditorSettingsModel(); console.log(evalSettings.baseUri); // => 'https://cdn.img.ly/packages/imgly/cesdk-react-native/1.73.1/assets' // Production — licensed with self-hosted assets const prodSettings = new EditorSettingsModel({ license: process.env.CESDK_LICENSE_KEY, userId: currentUser.id, baseUri: 'https://assets.myapp.com/cesdk/1.73.1/assets', } satisfies Partial); // Spread / partial override pattern const baseSettings: Partial = { license: 'LICENSE', baseUri: 'https://assets.myapp.com/cesdk/1.73.1/assets', }; const settingsForUser = new EditorSettingsModel({ ...baseSettings, userId: 'user-42' }); ``` -------------------------------- ### Opening iOS Editor Directly from Swift Source: https://context7.com/imgly/editor-react-native/llms.txt Use EditorSettings to configure editor parameters and then open a specific editor preset like video using IMGLYEditorModuleSwiftAdapter.shared.openEditor. This is useful for launching the editor from a native screen. ```swift import IMGLYEditorModule import IMGLYEditor import IMGLYEngine // Directly open the design editor from Swift (e.g. from a native screen) let settings = EditorSettings.fromDictionary([ "license": "YOUR_LICENSE_KEY", "baseUri": "https://cdn.img.ly/packages/imgly/cesdk-react-native/1.73.1/assets", "userId": "user-123", ])! let adapter = IMGLYEditorModuleSwiftAdapter.shared // Use built-in builder IMGLYEditorModuleSwiftAdapter.shared.builderClosure = { _, _ in EditorBuilder.video() } adapter.openEditor(.video, settings: settings, metadata: nil) { result, error in if let error { print("Error:", error); return } guard let result else { print("Cancelled"); return } print("Video exported to:", result.artifact ?? "n/a") print("Scene file at:", result.scene ?? "n/a") print("Thumbnail at:", result.thumbnail ?? "n/a") } ``` -------------------------------- ### Pre-load content with SourceType and Source Source: https://context7.com/imgly/editor-react-native/llms.txt Define the type of file URI for initial editor content using SourceType (IMAGE, VIDEO, SCENE). Use Source to pass remote or local file URIs, enabling round-trip editing for .scene files. ```typescript import IMGLYEditor, { EditorSettingsModel, EditorPreset, SourceType, type Source, } from '@imgly/editor-react-native'; const settings = new EditorSettingsModel({ license: 'YOUR_LICENSE_KEY' }); // Load a remote image into the photo editor const imageSource: Source = { source: 'https://example.com/portrait.jpg', type: SourceType.IMAGE, }; const photoResult = await IMGLYEditor.openEditor(settings, imageSource, EditorPreset.PHOTO); // Load a local video file (React Native file URI) const videoSource: Source = { source: 'file:///data/user/0/com.myapp/cache/clip.mp4', type: SourceType.VIDEO, }; const videoResult = await IMGLYEditor.openEditor(settings, videoSource, EditorPreset.VIDEO); // Re-open a previously exported scene for further editing const sceneSource: Source = { source: photoResult?.scene ?? 'file:///tmp/cesdk_export_scene_xxx.scene', type: SourceType.SCENE, }; const editedResult = await IMGLYEditor.openEditor(settings, sceneSource, EditorPreset.PHOTO); ``` -------------------------------- ### IMGLYEditor.openEditor Source: https://context7.com/imgly/editor-react-native/llms.txt The primary entry point for launching the fullscreen native editor. It returns a promise that resolves to `EditorResult | null`. Passing `null` as the license runs the SDK in evaluation mode. The `source` parameter allows pre-loading an existing asset. ```APIDOC ## IMGLYEditor.openEditor — Open an editor modal ### Description The primary entry point. Presents a fullscreen native editor and returns a promise that resolves to `EditorResult | null`. Passing `null` as the license runs the SDK in evaluation mode with a watermark. The `source` parameter lets you pre-load an existing image, video, or `.scene` file; omit it to start from a blank canvas. Cancelling the editor resolves the promise with `null` rather than rejecting it. ### Method `async` function ### Parameters - **settings** (`EditorSettingsModel`): Configuration settings for the editor. - **source** (`{ source: string, type: SourceType }`): Optional. An object specifying the source asset to load. - **source** (`string`): The URI of the source asset. - **type** (`SourceType`): The type of the source asset (e.g., `SourceType.IMAGE`). - **preset** (`EditorPreset`): The editor preset to use (e.g., `EditorPreset.PHOTO`). - **metadata** (`object`): Optional. Custom metadata to be forwarded to native callbacks. ### Response #### Success Response - **EditorResult** (`object`): An object containing the export results. - **artifact** (`string`): Path to the exported artifact. - **scene** (`string`): Path to the `.scene` file for reloading. - **thumbnail** (`string`): Path to a small preview PNG. - **metadata** (`object`): Custom metadata. - **null**: If the user cancels the editor. ### Request Example ```typescript import IMGLYEditor, { EditorSettingsModel, EditorPreset, SourceType, type EditorResult, } from '@imgly/editor-react-native'; async function openPhotoEditor(imageUri: string): Promise { const settings = new EditorSettingsModel({ license: 'YOUR_LICENSE_KEY', // pass undefined to run in evaluation mode userId: 'user-abc-123', // optional — used for MAU tracking // baseUri defaults to IMG.LY CDN; override to self-host assets: // baseUri: 'https://your-cdn.example.com/cesdk-assets', }); let result: EditorResult | null = null; try { result = await IMGLYEditor.openEditor( settings, { source: imageUri, type: SourceType.IMAGE }, // pre-load an image EditorPreset.PHOTO, { myCustomKey: 'myCustomValue' }, // optional metadata forwarded to native callbacks ); } catch (e) { console.error('Editor export failed:', e); return; } if (result === null) { console.log('User cancelled the editor'); return; } console.log('Exported artifact path:', result.artifact); // e.g. file:///tmp/export.png console.log('Scene path:', result.scene); // .scene file for reload console.log('Thumbnail path:', result.thumbnail); // small preview PNG console.log('Custom metadata:', result.metadata); // { [key]: unknown } } ``` ``` -------------------------------- ### EditorPreset - Choose an editor variant Source: https://context7.com/imgly/editor-react-native/llms.txt The `EditorPreset` enum allows selection of preconfigured editor UIs and scene defaults. Each preset offers a distinct default scene, toolbar, asset palette, and export format. ```APIDOC ## `EditorPreset` — Choose an editor variant An enum that selects which preconfigured editor UI and scene defaults to load. Each preset ships a distinct default scene file, toolbar layout, asset palette, and export format. ```typescript import IMGLYEditor, { EditorSettingsModel, EditorPreset } from '@imgly/editor-react-native'; const settings = new EditorSettingsModel({ license: 'YOUR_LICENSE_KEY' }); // Design editor — blank design scene, exports PDF await IMGLYEditor.openEditor(settings, undefined, EditorPreset.DESIGN); // Photo editor — blank image scene, exports PNG await IMGLYEditor.openEditor(settings, undefined, EditorPreset.PHOTO); // Postcard editor — two-sided postcard scene, exports PDF await IMGLYEditor.openEditor(settings, undefined, EditorPreset.POSTCARD); // Apparel editor — apparel scene with print area, exports PDF await IMGLYEditor.openEditor(settings, undefined, EditorPreset.APPAREL); // Video editor — blank video scene, exports MP4 await IMGLYEditor.openEditor(settings, undefined, EditorPreset.VIDEO); ``` ``` -------------------------------- ### iOS: Custom Scene Creation Source: https://context7.com/imgly/editor-react-native/llms.txt Customize the scene creation phase to load a remote scene instead of a blank photo template. Other phases use default implementations. ```swift import IMGLYEditor import IMGLYEngine // Customise only the scene-creation phase to load a custom template let customOnCreate = PhotoEditorConfiguration.defaultOnCreate( createScene: { engine in // Load a remote scene instead of the blank photo template let remoteURL = URL(string: "https://example.com/templates/portrait.scene")! try await engine.scene.load(from: remoteURL) }, // All other phases (preCreateScene, loadAssetSources, postCreateScene) use defaults ) // Apply in a SwiftUI editor view Editor(engineSettings) .imgly.configuration { PhotoEditorConfiguration { builder in builder.onCreate { engine, _ in try await customOnCreate(engine) } builder.onExport { engine, _, _ in let result = try await OnExport.export(engine, .jpeg) // handle result… } } } ``` -------------------------------- ### EditorSettingsModel Source: https://context7.com/imgly/editor-react-native/llms.txt A class used to configure the editor runtime, including license, CDN base URI, and user identity. ```APIDOC ## EditorSettingsModel — Configure the editor runtime ### Description A concrete implementation of the `EditorSettings` interface used to provide license, CDN base URI, and user identity to the native engine. The `baseUri` defaults to the versioned IMG.LY CDN path for the current SDK release but should be overridden in production to a self-hosted asset bundle. ### Constructor `new EditorSettingsModel(settings?: Partial)` ### Parameters - **settings** (`Partial`): Optional. An object containing settings to configure the editor. - **license** (`string`): Your license key. Pass `undefined` to run in evaluation mode. - **userId** (`string`): Optional. A unique identifier for the user, used for MAU tracking. - **baseUri** (`string`): Optional. The base URI for assets. Defaults to the IMG.LY CDN. Override to self-host assets. ### Properties - **baseUri** (`string`): The base URI for assets. ### Request Example ```typescript import { EditorSettingsModel, type EditorSettings } from '@imgly/editor-react-native'; // Minimal — evaluation mode (watermark shown) const evalSettings = new EditorSettingsModel(); console.log(evalSettings.baseUri); // => 'https://cdn.img.ly/packages/imgly/cesdk-react-native/1.73.1/assets' // Production — licensed with self-hosted assets const prodSettings = new EditorSettingsModel({ license: process.env.CESDK_LICENSE_KEY, userId: currentUser.id, baseUri: 'https://assets.myapp.com/cesdk/1.73.1/assets', } satisfies Partial); // Spread / partial override pattern const baseSettings: Partial = { license: 'LICENSE', baseUri: 'https://assets.myapp.com/cesdk/1.73.1/assets', }; const settingsForUser = new EditorSettingsModel({ ...baseSettings, userId: 'user-42' }); ``` ``` -------------------------------- ### Choose an editor preset with EditorPreset Source: https://context7.com/imgly/editor-react-native/llms.txt Use the EditorPreset enum to select a preconfigured UI and scene for the editor. Each preset defines default scene files, toolbar layouts, asset palettes, and export formats. ```typescript import IMGLYEditor, { EditorSettingsModel, EditorPreset } from '@imgly/editor-react-native'; const settings = new EditorSettingsModel({ license: 'YOUR_LICENSE_KEY' }); // Design editor — blank design scene, exports PDF await IMGLYEditor.openEditor(settings, undefined, EditorPreset.DESIGN); // Photo editor — blank image scene, exports PNG await IMGLYEditor.openEditor(settings, undefined, EditorPreset.PHOTO); // Postcard editor — two-sided postcard scene, exports PDF await IMGLYEditor.openEditor(settings, undefined, EditorPreset.POSTCARD); // Apparel editor — apparel scene with print area, exports PDF await IMGLYEditor.openEditor(settings, undefined, EditorPreset.APPAREL); // Video editor — blank video scene, exports MP4 await IMGLYEditor.openEditor(settings, undefined, EditorPreset.VIDEO); ``` -------------------------------- ### SourceType & Source - Pre-load content into the editor Source: https://context7.com/imgly/editor-react-native/llms.txt The `SourceType` and `Source` types enable pre-loading content into the editor. Supported source types include `IMAGE`, `VIDEO`, and `SCENE` for round-trip editing. ```APIDOC ## `SourceType` & `Source` — Pre-load content into the editor Defines the type of file URI passed to the editor as its initial content. Use `IMAGE` for raster images, `VIDEO` for video files, and `SCENE` for previously exported `.scene` files enabling round-trip editing. ```typescript import IMGLYEditor, { EditorSettingsModel, EditorPreset, SourceType, type Source, } from '@imgly/editor-react-native'; const settings = new EditorSettingsModel({ license: 'YOUR_LICENSE_KEY' }); // Load a remote image into the photo editor const imageSource: Source = { source: 'https://example.com/portrait.jpg', type: SourceType.IMAGE, }; const photoResult = await IMGLYEditor.openEditor(settings, imageSource, EditorPreset.PHOTO); // Load a local video file (React Native file URI) const videoSource: Source = { source: 'file:///data/user/0/com.myapp/cache/clip.mp4', type: SourceType.VIDEO, }; const videoResult = await IMGLYEditor.openEditor(settings, videoSource, EditorPreset.VIDEO); // Re-open a previously exported scene for further editing const sceneSource: Source = { source: photoResult?.scene ?? 'file:///tmp/cesdk_export_scene_xxx.scene', type: SourceType.SCENE, }; const editedResult = await IMGLYEditor.openEditor(settings, sceneSource, EditorPreset.PHOTO); ``` ``` -------------------------------- ### iOS: Force Crop on Loaded Images Source: https://context7.com/imgly/editor-react-native/llms.txt Enforces a set of allowed crop aspect ratios when a scene is loaded. Combine with the default onLoaded handler using the `existing` continuation. This handler is registered as the onLoaded callback. ```swift import IMGLYEditor import IMGLYEngine // Register the force-crop handler as the onLoaded callback Editor(engineSettings) .imgly.configuration { PhotoEditorConfiguration { builder in builder.onLoaded { context, existing in // Enforce 1:1, 16:9, or 9:16 crops only if let page = try context.engine.scene.getPages().first { context.eventHandler.send( .applyForceCrop( to: page, with: [ ForceCropPreset(sourceID: "ly.img.crop.presets", presetID: "aspect-ratio-1-1"), ForceCropPreset(sourceID: "ly.img.crop.presets", presetID: "aspect-ratio-16-9"), ForceCropPreset(sourceID: "ly.img.crop.presets", presetID: "aspect-ratio-9-16"), ], mode: .ifNeeded, // only crop if the current ratio is not in the allowed set ), ) } try await existing() // always call existing to complete default onLoaded logic } } } ``` -------------------------------- ### iOS: Custom Modal Editor Configuration Source: https://context7.com/imgly/editor-react-native/llms.txt Overrides the default close/back button behavior in the navigation bar with a custom action. The bundled implementation replaces it with a 'Home' button that resolves the React Native promise with `nil` (user cancelled). Extend or replace it to navigate to a specific screen on close. ```swift import IMGLYEditorModule import IMGLYEditor import SwiftUI // Custom modal config that calls a completion closure on close/error final class MyModalEditorConfiguration: EditorConfiguration { private let onClose: (EditorResult?) -> Void init(onClose: @escaping (EditorResult?) -> Void) { self.onClose = onClose super.init() } override var navigationBar: NavigationBar.Configuration? { NavigationBar.Configuration { navBuilder in navBuilder.modify { [onClose] _, items in items.replace(id: NavigationBar.Buttons.ID.closeEditor) { NavigationBar.Buttons.closeEditor( action: { _ in onClose(nil) }, // resolve with nil = cancelled label: { _ in SwiftUI.Label("Cancel", systemImage: "xmark") }, ) } } } } override var onError: OnError.Handler? { { [onClose] error, eventHandler, _ in eventHandler.send(.showErrorAlert(error) { onClose(nil) }) } } } // Usage in a custom EditorBuilder let myBuilder: EditorBuilder.Builder = { settings, preset, metadata, result in UIHostingController(rootView: NavigationView { Editor(EngineSettings(license: settings.license)) .imgly.configuration { DesignEditorConfiguration { builder in builder.onExport { engine, _, _ in let editorResult = try await OnExport.export(engine, .pdf) result(.success(editorResult)) } } MyModalEditorConfiguration { exportResult in result(.success(exportResult)) } } }.navigationViewStyle(.stack)) } ``` -------------------------------- ### EditorResult - Inspect export output Source: https://context7.com/imgly/editor-react-native/llms.txt The `EditorResult` object is resolved by `openEditor` upon successful export. It contains URIs for the exported artifact, a `.scene` file for round-trip editing, and a thumbnail preview. ```APIDOC ## `EditorResult` — Inspect export output The object resolved by `openEditor` on a successful export. Contains file URIs for the primary artifact, a `.scene` file for round-trip editing, and a thumbnail preview. On Android, `content://` URIs in the scene string may not be resolvable outside the originating app context; use `EngineConfiguration.onUpload` and `engine.editor.setUriResolver` to normalise them. ```typescript import IMGLYEditor, { EditorSettingsModel, EditorPreset } from '@imgly/editor-react-native'; import RNFS from 'react-native-fs'; // example: react-native-fs for file operations const settings = new EditorSettingsModel({ license: 'YOUR_LICENSE_KEY' }); const result = await IMGLYEditor.openEditor(settings, undefined, EditorPreset.DESIGN); if (result) { // result.artifact — URI of the exported file (PNG / PDF / MP4 depending on preset) if (result.artifact) { await RNFS.copyFile( result.artifact.replace('file://', ''), RNFS.DocumentDirectoryPath + '/my-design.pdf', ); console.log('Saved design to documents'); } // result.scene — URI of the .scene file for future re-editing if (result.scene) { console.log('Scene saved at:', result.scene); } // result.thumbnail — URI of a small PNG preview (~100px tall) if (result.thumbnail) { console.log('Thumbnail:', result.thumbnail); } // result.metadata — custom key/value data injected via onExport native callback console.log('Export metadata:', result.metadata); // e.g. { exportFormat: 'pdf', pageCount: 2 } } ``` ``` -------------------------------- ### Inspect export output with EditorResult Source: https://context7.com/imgly/editor-react-native/llms.txt The EditorResult object, resolved by openEditor, contains URIs for the exported artifact, a .scene file for re-editing, and a thumbnail preview. Handle potential content:// URI issues on Android by using EngineConfiguration.onUpload and engine.editor.setUriResolver. ```typescript import IMGLYEditor, { EditorSettingsModel, EditorPreset } from '@imgly/editor-react-native'; import RNFS from 'react-native-fs'; // example: react-native-fs for file operations const settings = new EditorSettingsModel({ license: 'YOUR_LICENSE_KEY' }); const result = await IMGLYEditor.openEditor(settings, undefined, EditorPreset.DESIGN); if (result) { // result.artifact — URI of the exported file (PNG / PDF / MP4 depending on preset) if (result.artifact) { await RNFS.copyFile( result.artifact.replace('file://', ''), RNFS.DocumentDirectoryPath + '/my-design.pdf', ); console.log('Saved design to documents'); } // result.scene — URI of the .scene file for future re-editing if (result.scene) { console.log('Scene saved at:', result.scene); } // result.thumbnail — URI of a small PNG preview (~100px tall) if (result.thumbnail) { console.log('Thumbnail:', result.thumbnail); } // result.metadata — custom key/value data injected via onExport native callback console.log('Export metadata:', result.metadata); // e.g. { exportFormat: 'pdf', pageCount: 2 } } ``` -------------------------------- ### Customizing iOS Editor Builder Closure in Swift Source: https://context7.com/imgly/editor-react-native/llms.txt Override IMGLYEditorModuleSwiftAdapter.shared.builderClosure in your AppDelegate to inject a custom editor configuration. This allows replacing the default preset builder with a custom SwiftUI view controller for specific presets like photo. ```swift import IMGLYEditorModule import IMGLYEditor import SwiftUI @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { // Override the builder closure to inject a custom editor configuration IMGLYEditorModuleSwiftAdapter.shared.builderClosure = { preset, metadata in switch preset { case .photo: // Return a custom photo editor builder return EditorBuilder.custom { settings, _, _, result in NavigationView { Editor(EngineSettings(license: settings.license, userID: settings.userId)) .imgly.configuration { PhotoEditorConfiguration { builder in builder.onCreate { engine, _ in // Custom scene creation: load from a bundled template let templateURL = Bundle.main.url(forResource: "my_template", withExtension: "scene")! try await engine.scene.load(from: templateURL) } builder.onExport { engine, eventHandler, _ in let editorResult = try await OnExport.export(engine, .png) result(.success(editorResult)) } } } }.navigationViewStyle(.stack) } default: // Fall back to the default builder for all other presets return EditorBuilder.design() } } return true } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.