Skip to main content
Muta allows you to emit custom events from your flows using the platform’s behavior system. You can configure custom events in the Muta web editor and listen for them in your app to trigger specific actions.

Setting Up Custom Events

  1. In the Muta web editor, add an “Emit Event” behavior to any element
  2. Give your event a unique name (e.g., signup_started, premium_selected, survey_completed)
  3. Optionally add custom data to pass along with the event

Example Usage

import MutaSDK
import SwiftUI

struct OnboardingView: View {
    @State private var isPremiumUser = false
    @State private var surveyData: [String: Any] = [:]
    
    var body: some View {
        VStack {
            // Your content
        }
        .onAppear {
            setupCustomEventHandlers()
        }
    }
    
    private func setupCustomEventHandlers() {
        // Listen for custom events
        let subscription = Muta.shared.on(CustomEvent.self) { event in
            switch event.type {
            case "signup_started":
                // Handle signup button click
                print("User started signup process")
                navigateToSignup()
                
            case "premium_selected":
                // Handle premium selection with custom data
                if let planType = event.eventData?["planType"] as? String,
                   let price = event.eventData?["price"] as? Double {
                    print("User selected \(planType) plan at $\(price)")
                    isPremiumUser = true
                }
                
            case "survey_completed":
                // Handle survey completion
                if let answers = event.eventData?["answers"] as? [String: Any] {
                    print("Survey completed with answers: \(answers)")
                    surveyData = answers
                    saveSurveyToBackend(answers)
                }
                
            case "form_submitted":
                // Handle form submission
                if let formData = event.eventData {
                    processFormData(formData)
                }
                
            default:
                print("Received custom event: \(event.type)")
            }
        }
        
        // Show the placement
        Muta.shared.displayPlacement(
            placementId: "your-placement-id",
            backgroundColor: .white
        )
    }
}

Custom Event Structure

struct CustomEvent: MutaEvent {
    let type: String           // Your custom event name
    let timestamp: Int         // Unix timestamp in ms
    let placementId: String    // ID of the placement
    let flowName: String?      // Name of the flow (if configured)
    let screenIndex: Int?      // Current screen index
    let eventData: [String: Any]?  // Custom data from the editor
}

Common Use Cases

User Actions

Track when users click specific CTAs or make choices:
Muta.shared.on(CustomEvent.self) { event in
    if event.type == "cta_clicked" {
        let buttonName = event.eventData?["buttonName"] as? String
        analytics.track("CTA Click", ["button": buttonName ?? "unknown"])
    }
}
Trigger app navigation based on flow interactions:
Muta.shared.on(CustomEvent.self) { event in
    switch event.type {
    case "go_to_home":
        navigationController.popToRootViewController(animated: true)
    case "open_settings":
        presentSettingsScreen()
    default:
        break
    }
}

Data Collection

Gather form submissions or survey responses:
Muta.shared.on(CustomEvent.self) { event in
    if event.type == "preferences_selected" {
        if let preferences = event.eventData?["preferences"] as? [String] {
            UserDefaults.standard.set(preferences, forKey: "userPreferences")
        }
    }
}

Feature Flags

Enable/disable features based on onboarding choices:
Muta.shared.on(CustomEvent.self) { event in
    if event.type == "feature_toggle" {
        if let featureName = event.eventData?["feature"] as? String,
           let enabled = event.eventData?["enabled"] as? Bool {
            FeatureFlags.shared.setFeature(featureName, enabled: enabled)
        }
    }
}

Best Practices

  1. Consistent Naming: Use descriptive, consistent event names across your flows
  2. Type Safety: Consider creating an enum for your event types to avoid typos
  3. Error Handling: Always validate eventData before using it
  4. Documentation: Document your custom events and their expected data structure
  5. Analytics Integration: Forward custom events to your analytics provider for tracking