Skip to main content
ExodeUI

EXODEUI DESKTOP

A little space for good ideas.

Choose your platform to get the official ExodeUI installer.

Looking for Intel Mac or other builds? Explore the web studio or check all download options.

Prefer the browser? Try for free in your browser →
All Packages
Swift

Swift Runtime

Official Swift Package Manager runtime for iOS 14+ and macOS 11+.

ExodeUI
Installation

Add SPM / pubspec dependency manually

Getting Started

The Swift runtime provides SwiftUI components wrapping a WKWebView engine bridge for native Apple platform support.

iOS 14+ & macOS 11+
SwiftUI native views
@MainActor controller API

ExodeUICanvas (SwiftUI)

swift
public struct ExodeUICanvas {
    public init(
        artboardJson: String,
        fit: String = "Contain",
        alignment: String = "Center",
        controller: ExodeUIController? = nil,
        onReady: (() -> Void)? = nil,
        onTrigger: ((String, String) -> Void)? = nil,
        onNavigation: ((String) -> Void)? = nil
    )
}

ExodeUIController

swift
@MainActor
public class ExodeUIController: ObservableObject {
    public init()
    public func fireTrigger(_ name: String)
    public func setInputBool(_ name: String, _ value: Bool)
    public func setInputNumber(_ name: String, _ value: Double)
    public func setInputText(_ name: String, _ value: String)
}

Swift Usage Example

swift
import SwiftUI
import ExodeUI

struct AnimationView: View {
    @StateObject private var controller = ExodeUIController()
    let artboardDataString = "..."

    var body: some View {
        VStack {
            ExodeUICanvas(
                artboardJson: artboardDataString,
                fit: "Contain",
                alignment: "Center",
                controller: controller,
                onReady: { print("Canvas Ready") },
                onTrigger: { name, anim in
                    print("Trigger \(name) on \(anim)")
                },
                onNavigation: { value in
                    print("Navigate: \(value)")
                }
            )
            .frame(width: 350, height: 350)

            Button("Fire Event") {
                controller.fireTrigger("Jump")
                controller.setInputBool("IsActive", true)
            }
        }
    }
}