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:
- Flow Started
case flowStarted(FlowStartedEvent)
// Properties: placementId, flowName?, totalScreens, timestamp
- Screen Viewed
case screenViewed(ScreenViewedEvent)
// Properties: placementId, flowName?, screenIndex, totalScreens, screenName?, timestamp
- Flow Completed
case flowCompleted(FlowCompletedEvent)
// Properties: placementId, flowName, screenIndex, totalScreens, screenName, timestamp
- Flow Abandoned
case flowAbandoned(FlowAbandonedEvent)
// Properties: placementId, flowName?, screenIndex, totalScreens, lastScreenIndex, screenName?, timestamp
- User Input Final
case userInputFinal(UserInputFinalEvent)
// Properties: placementId, flowName?, timestamp, userInputs
- 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
-
Event Naming: Use consistent event naming conventions across your analytics platform.
-
Data Enrichment: Add additional context to events when needed (e.g., user ID, app version).
-
Error Handling: Implement proper error handling for analytics tracking.