1.1.5: conversion funnel overhaul
Paywall: - Redesigned PremiumView with yearly/monthly/lifetime side by side - 7-day free trial badge with savings % vs monthly - Social proof line, BEST VALUE highlight on yearly - StoreManager: new yearlyProduct, lifetimeProduct, yearlySavingsPercent, hasTrialAvailable Funnel: - Paywall step added to onboarding (PaywallStepView) - Contextual modal at dish limit (replaces silent block) - Visible "X/15 dishes" counter in DishListView - BottomPromoBanner rotates AdMob with internal "Remove ads" CTA (1 in 4) - Free dish limit lowered 20 → 15 - Review prompt earlier: 2 weeks → 1 week Analytics: - paywall_viewed/dismissed with source + seconds_on_screen - dish_limit_hit, week_limit_hit, free_trial_started events - Every PremiumView call site now passes its source StoreKit: - MealMood.storekit: added yearly $19.99 + 7d trial, monthly trial, lifetime $39.99 - AppStoreConnect-1.1.5-setup.md with full manual setup instructions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,13 @@ enum AnalyticsEvent {
|
||||
|
||||
// Feedback loop
|
||||
static let weekRated = "week_rated"
|
||||
|
||||
// Conversion funnel (1.1.5)
|
||||
static let paywallViewed = "paywall_viewed"
|
||||
static let paywallDismissed = "paywall_dismissed"
|
||||
static let dishLimitHit = "dish_limit_hit"
|
||||
static let weekLimitHit = "week_limit_hit"
|
||||
static let freeTrialStarted = "free_trial_started"
|
||||
}
|
||||
|
||||
enum AnalyticsService {
|
||||
@@ -118,4 +125,28 @@ enum AnalyticsService {
|
||||
let value = rating == 1 ? "liked" : rating == -1 ? "disliked" : "cleared"
|
||||
logEvent(AnalyticsEvent.weekRated, parameters: ["rating": value])
|
||||
}
|
||||
|
||||
static func logPaywallViewed(source: String) {
|
||||
logEvent(AnalyticsEvent.paywallViewed, parameters: ["source": source])
|
||||
}
|
||||
|
||||
static func logPaywallDismissed(source: String, secondsOnScreen: Int, didConvert: Bool) {
|
||||
logEvent(AnalyticsEvent.paywallDismissed, parameters: [
|
||||
"source": source,
|
||||
"seconds_on_screen": secondsOnScreen,
|
||||
"did_convert": didConvert
|
||||
])
|
||||
}
|
||||
|
||||
static func logDishLimitHit() {
|
||||
logEvent(AnalyticsEvent.dishLimitHit)
|
||||
}
|
||||
|
||||
static func logWeekLimitHit() {
|
||||
logEvent(AnalyticsEvent.weekLimitHit)
|
||||
}
|
||||
|
||||
static func logFreeTrialStarted(plan: String) {
|
||||
logEvent(AnalyticsEvent.freeTrialStarted, parameters: ["plan": plan])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user