Files
honeyDueKMP/iosApp/iosApp/Subscription/SubscriptionCache.swift
Trey t d12a2d315c Implement freemium subscription system - iOS UI (Phase 5)
iOS Subscription Features:
- Complete SwiftUI subscription UI components
- SubscriptionCache wrapper for accessing Kotlin state
- SubscriptionHelper wrapper for limit checking
- Upgrade prompt and feature comparison screens

Components Created:
1. SubscriptionCache.swift
   - Swift wrapper for Kotlin SubscriptionCache
   - ObservableObject for reactive UI updates
   - Manages currentSubscription state

2. SubscriptionHelper.swift
   - Swift wrapper for Kotlin SubscriptionHelper
   - canAddProperty(), canAddTask()
   - shouldShowUpgradePromptForContractors/Documents()

3. UpgradeFeatureView.swift
   - Full-screen view for restricted features
   - Shows when free users navigate to contractors/documents
   - Beautiful upgrade prompt with feature icon and description
   - "Upgrade to Pro" button

4. UpgradePromptView.swift
   - Modal upgrade dialog
   - Shows when limits are reached (property/task limits)
   - Displays trigger-specific messaging
   - Quick feature preview
   - Compare plans button

5. FeatureComparisonView.swift
   - Free vs Pro tier comparison table
   - Loads feature benefits from backend
   - Shows all feature differences
   - Upgrade button

6. StoreKitManager.swift
   - StoreKit 2 integration (placeholder)
   - Product loading and purchase methods
   - Receipt verification hooks
   - Transaction observer
   - NOTE: Requires App Store Connect configuration

Usage:
- Use UpgradeFeatureView for contractors/documents screens
- Use UpgradePromptView when limits are reached
- SubscriptionHelper checks limits before actions

Next: Integrate into contractors/documents screens

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 13:35:25 -06:00

45 lines
1.4 KiB
Swift

import SwiftUI
import ComposeApp
/// Swift wrapper for accessing Kotlin SubscriptionCache
class SubscriptionCacheWrapper: ObservableObject {
static let shared = SubscriptionCacheWrapper()
@Published var currentSubscription: SubscriptionStatus?
@Published var upgradeTriggers: [String: UpgradeTriggerData] = [:]
@Published var featureBenefits: [FeatureBenefit] = []
@Published var promotions: [Promotion] = []
private init() {
// Initialize with current values from Kotlin cache
Task {
await observeSubscriptionStatus()
}
}
@MainActor
private func observeSubscriptionStatus() {
// Update from Kotlin cache
if let subscription = ComposeApp.SubscriptionCache.shared.currentSubscription.value as? SubscriptionStatus {
self.currentSubscription = subscription
}
}
func updateSubscription(_ subscription: SubscriptionStatus) {
ComposeApp.SubscriptionCache.shared.updateSubscriptionStatus(subscription: subscription)
DispatchQueue.main.async {
self.currentSubscription = subscription
}
}
func clear() {
ComposeApp.SubscriptionCache.shared.clear()
DispatchQueue.main.async {
self.currentSubscription = nil
self.upgradeTriggers = [:]
self.featureBenefits = []
self.promotions = []
}
}
}