122 lines
3.8 KiB
Swift
122 lines
3.8 KiB
Swift
//
|
|
// ClickyAnalytics.swift
|
|
// leanring-buddy
|
|
//
|
|
// Centralized PostHog analytics wrapper. All event names and properties
|
|
// are defined here so instrumentation is consistent and easy to audit.
|
|
//
|
|
|
|
import Foundation
|
|
import PostHog
|
|
|
|
enum ClickyAnalytics {
|
|
|
|
// MARK: - Setup
|
|
|
|
static func configure() {
|
|
let config = PostHogConfig(
|
|
apiKey: "phc_xcQPygmhTMzzYh8wNW92CCwoXmnzqyChAixh8zgpqC3C",
|
|
host: "https://us.i.posthog.com"
|
|
)
|
|
PostHogSDK.shared.setup(config)
|
|
}
|
|
|
|
// MARK: - App Lifecycle
|
|
|
|
/// Fired once on every app launch in applicationDidFinishLaunching.
|
|
static func trackAppOpened() {
|
|
let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "unknown"
|
|
PostHogSDK.shared.capture("app_opened", properties: [
|
|
"app_version": version
|
|
])
|
|
}
|
|
|
|
// MARK: - Onboarding
|
|
|
|
/// User clicked the Start button to begin onboarding for the first time.
|
|
static func trackOnboardingStarted() {
|
|
PostHogSDK.shared.capture("onboarding_started")
|
|
}
|
|
|
|
/// User clicked "Watch Onboarding Again" from the panel footer.
|
|
static func trackOnboardingReplayed() {
|
|
PostHogSDK.shared.capture("onboarding_replayed")
|
|
}
|
|
|
|
/// The onboarding video finished playing to the end.
|
|
static func trackOnboardingVideoCompleted() {
|
|
PostHogSDK.shared.capture("onboarding_video_completed")
|
|
}
|
|
|
|
/// The 40s onboarding demo interaction where Clicky points at something.
|
|
static func trackOnboardingDemoTriggered() {
|
|
PostHogSDK.shared.capture("onboarding_demo_triggered")
|
|
}
|
|
|
|
// MARK: - Permissions
|
|
|
|
/// All three permissions (accessibility, screen recording, mic) are granted.
|
|
static func trackAllPermissionsGranted() {
|
|
PostHogSDK.shared.capture("all_permissions_granted")
|
|
}
|
|
|
|
/// A single permission was granted. Called when polling detects a change.
|
|
static func trackPermissionGranted(permission: String) {
|
|
PostHogSDK.shared.capture("permission_granted", properties: [
|
|
"permission": permission
|
|
])
|
|
}
|
|
|
|
// MARK: - Voice Interaction
|
|
|
|
/// User pressed the push-to-talk shortcut (control+option) to start talking.
|
|
static func trackPushToTalkStarted() {
|
|
PostHogSDK.shared.capture("push_to_talk_started")
|
|
}
|
|
|
|
/// User released the shortcut — transcript is being finalized.
|
|
static func trackPushToTalkReleased() {
|
|
PostHogSDK.shared.capture("push_to_talk_released")
|
|
}
|
|
|
|
/// Transcription completed and the user's message is being sent to the AI.
|
|
static func trackUserMessageSent(transcript: String) {
|
|
PostHogSDK.shared.capture("user_message_sent", properties: [
|
|
"transcript": transcript,
|
|
"character_count": transcript.count
|
|
])
|
|
}
|
|
|
|
/// Claude responded and the response is being spoken via TTS.
|
|
static func trackAIResponseReceived(response: String) {
|
|
PostHogSDK.shared.capture("ai_response_received", properties: [
|
|
"response": response,
|
|
"character_count": response.count
|
|
])
|
|
}
|
|
|
|
/// Claude's response included a [POINT:x,y:label] coordinate tag,
|
|
/// so the buddy is flying to point at a UI element.
|
|
static func trackElementPointed(elementLabel: String?) {
|
|
PostHogSDK.shared.capture("element_pointed", properties: [
|
|
"element_label": elementLabel ?? "unknown"
|
|
])
|
|
}
|
|
|
|
// MARK: - Errors
|
|
|
|
/// An error occurred during the AI response pipeline.
|
|
static func trackResponseError(error: String) {
|
|
PostHogSDK.shared.capture("response_error", properties: [
|
|
"error": error
|
|
])
|
|
}
|
|
|
|
/// An error occurred during TTS playback.
|
|
static func trackTTSError(error: String) {
|
|
PostHogSDK.shared.capture("tts_error", properties: [
|
|
"error": error
|
|
])
|
|
}
|
|
}
|