Muta provides a flexible event system that works with any analytics provider (Mixpanel, AppsFlyer, Amplitude, Firebase, etc.). Events are emitted during key user interactions, allowing you to track and analyze your placement performance.

Basic Integration

Here’s a simple example of how to integrate analytics with your Muta placements:

import MutaSDK

class AnalyticsManager {
    var subscription: Subscription?
    
    func setupTracking() {
        subscription = Muta.shared.on { event in
            switch event {
            case .flowStarted(let event):
                Analytics.track("Flow Started", properties: [
                    "placement_id": event.placementId,
                    "flow_name": event.flowName ?? "",
                    "total_screens": event.totalScreens,
                    "timestamp": event.timestamp
                ])
                
            case .flowCompleted(let event):
                Analytics.track("Flow Completed", properties: [
                    "placement_id": event.placementId,
                    "flow_name": event.flowName,
                    "screen_index": event.screenIndex,
                    "total_screens": event.totalScreens,
                    "timestamp": event.timestamp
                ])
                
            // Handle other events...
            }
        }
    }
    
    deinit {
        subscription?.remove()
    }
}

Available Events

The SDK emits various events that you can listen to:

  1. Flow Started
case flowStarted(FlowStartedEvent)
// Properties: placementId, flowName?, totalScreens, timestamp
  1. Screen Viewed
case screenViewed(ScreenViewedEvent)
// Properties: placementId, flowName?, screenIndex, totalScreens, screenName?, timestamp
  1. Flow Completed
case flowCompleted(FlowCompletedEvent)
// Properties: placementId, flowName, screenIndex, totalScreens, screenName, timestamp
  1. Flow Abandoned
case flowAbandoned(FlowAbandonedEvent)
// Properties: placementId, flowName?, screenIndex, totalScreens, lastScreenIndex, screenName?, timestamp
  1. User Input Final
case userInputFinal(UserInputFinalEvent)
// Properties: placementId, flowName?, timestamp, userInputs
  1. Error Events
case error(ErrorEvent)
// Types: .network(message, timestamp) or .placement(message, code, timestamp, placementId)

Integration Examples

Mixpanel Example

import MutaSDK
import Mixpanel

class MixpanelAnalytics {
    var subscription: Subscription?
    
    func setupTracking() {
        subscription = Muta.shared.on { event in
            switch event {
            case .flowCompleted(let event):
                Mixpanel.mainInstance().track(
                    event: "Onboarding Complete",
                    properties: [
                        "flow_name": event.flowName,
                        "total_screens": event.totalScreens,
                        "user_inputs": event.userInputs
                    ]
                )
                
            case .flowAbandoned(let event):
                Mixpanel.mainInstance().track(
                    event: "Onboarding Abandoned",
                    properties: [
                        "flow_name": event.flowName ?? "",
                        "last_screen_index": event.lastScreenIndex,
                        "total_screens": event.totalScreens
                    ]
                )
                
            default:
                break
            }
        }
    }
    
    deinit {
        subscription?.remove()
    }
}

AppsFlyer Example

import MutaSDK
import AppsFlyerLib

class AppsFlyerAnalytics {
    var subscription: Subscription?
    
    func setupTracking() {
        subscription = Muta.shared.on { event in
            let eventName = "onboarding_\(event.type)"
            var properties: [String: Any] = [
                "placement_id": event.placementId,
                "flow_name": event.flowName ?? "",
                "timestamp": Date(timeIntervalSince1970: TimeInterval(event.timestamp / 1000))
            ]
            
            // Add event-specific properties
            switch event {
            case .flowStarted(let event):
                properties["total_screens"] = event.totalScreens
                
            case .screenViewed(let event):
                properties["screen_index"] = event.screenIndex
                properties["total_screens"] = event.totalScreens
                properties["screen_name"] = event.screenName ?? ""
                
            case .flowCompleted(let event):
                properties["screen_index"] = event.screenIndex
                properties["total_screens"] = event.totalScreens
                properties["screen_name"] = event.screenName
                
            case .flowAbandoned(let event):
                properties["screen_index"] = event.screenIndex
                properties["total_screens"] = event.totalScreens
                properties["last_screen_index"] = event.lastScreenIndex
                properties["screen_name"] = event.screenName ?? ""
                
            case .userInputFinal(let event):
                properties["user_inputs"] = event.userInputs
                
            case .error(let error):
                switch error {
                case .network(let message, _):
                    properties["error_message"] = message
                    properties["error_type"] = "network"
                    
                case .placement(let message, let code, _, _):
                    properties["error_message"] = message
                    properties["error_code"] = code
                    properties["error_type"] = "placement"
                @unknown default:
                    break
                }
            @unknown default:
                break
            }
            
            AppsFlyerLib.shared().logEvent(eventName, withValues: properties)
        }
    }
    
    deinit {
        subscription?.remove()
    }
}

Best Practices

  1. Event Naming: Use consistent event naming conventions across your analytics platform.

  2. Data Enrichment: Add additional context to events when needed (e.g., user ID, app version).

  3. Error Handling: Implement proper error handling for analytics tracking.