Harden iOS app with audit fixes, UI consistency, and sheet race condition fixes

Applies verified fixes from deep audit (concurrency, performance, security,
accessibility), standardizes CRUD form buttons to Add/Save pattern, removes
.drawingGroup() that broke search bar TextFields, and converts vulnerable
.sheet(isPresented:) + if-let patterns to safe presentation to prevent
blank white modals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-03-06 09:59:56 -06:00
parent 61ab95d108
commit 9c574c4343
76 changed files with 824 additions and 971 deletions
@@ -6,6 +6,10 @@ import ComposeApp
@MainActor
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
/// Throttle subscription refreshes to at most once every 5 minutes
private static var lastSubscriptionRefresh: Date?
private static let subscriptionRefreshInterval: TimeInterval = 300 // 5 minutes
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
@@ -45,10 +49,17 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele
// Clear badge when app becomes active
PushNotificationManager.shared.clearBadge()
// Refresh StoreKit subscription status when app comes to foreground
// Refresh StoreKit subscription status when app comes to foreground (throttled to every 5 min)
// This ensures we have the latest subscription state if it changed while app was in background
Task {
await StoreKitManager.shared.refreshSubscriptionStatus()
let now = Date()
if let lastRefresh = Self.lastSubscriptionRefresh,
now.timeIntervalSince(lastRefresh) < Self.subscriptionRefreshInterval {
// Skip refreshed recently
} else {
Self.lastSubscriptionRefresh = now
Task {
await StoreKitManager.shared.refreshSubscriptionStatus()
}
}
}