Fix feels://subscribe deep link on cold launch via app.open()

When XCUITest calls app.open(url), the app relaunches (cold launch) and
onOpenURL doesn't fire reliably. Capture the URL from launch options in
AppDelegate and check it on appear with a short delay to ensure the view
hierarchy is ready for sheet presentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-20 11:58:12 -06:00
parent f495ae90fa
commit 5b8a98f763
2 changed files with 18 additions and 4 deletions

View File

@@ -11,11 +11,16 @@ import UIKit
import SwiftUI import SwiftUI
class AppDelegate: NSObject, UIApplicationDelegate { class AppDelegate: NSObject, UIApplicationDelegate {
static var pendingDeepLinkURL: URL?
private let savedOnboardingData = UserDefaultsStore.getOnboarding() private let savedOnboardingData = UserDefaultsStore.getOnboarding()
@AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system @AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system
@MainActor @MainActor
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
if let url = launchOptions?[.url] as? URL {
AppDelegate.pendingDeepLinkURL = url
}
DataController.shared.removeNoForDates() DataController.shared.removeNoForDates()
DataController.shared.fillInMissingDates() DataController.shared.fillInMissingDates()
UNUserNotificationCenter.current().delegate = self UNUserNotificationCenter.current().delegate = self

View File

@@ -63,9 +63,7 @@ struct FeelsApp: App {
.environmentObject(iapManager) .environmentObject(iapManager)
} }
.onOpenURL { url in .onOpenURL { url in
if url.scheme == "feels" && url.host == "subscribe" { handleDeepLink(url)
showSubscriptionFromWidget = true
}
} }
.alert("Data Storage Unavailable", .alert("Data Storage Unavailable",
isPresented: $showStorageFallbackAlert) { isPresented: $showStorageFallbackAlert) {
@@ -77,6 +75,12 @@ struct FeelsApp: App {
if SharedModelContainer.isUsingInMemoryFallback { if SharedModelContainer.isUsingInMemoryFallback {
AnalyticsManager.shared.track(.storageFallbackActivated) AnalyticsManager.shared.track(.storageFallbackActivated)
} }
if let url = AppDelegate.pendingDeepLinkURL {
AppDelegate.pendingDeepLinkURL = nil
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
handleDeepLink(url)
}
}
} }
// Lock screen overlay // Lock screen overlay
@@ -142,4 +146,9 @@ struct FeelsApp: App {
} }
} }
private func handleDeepLink(_ url: URL) {
if url.scheme == "feels" && url.host == "subscribe" {
showSubscriptionFromWidget = true
}
}
} }