Fix subscription screen hanging on "Loading Subscription"

The .containerRelativeFrame(.horizontal) on the marketing content
caused an infinite layout loop inside SubscriptionStoreView's scroll
container. Replaced with .frame(maxWidth: .infinity).

Also fixes leading space in StoreKit config display name, adds
debug logging to product loading, and reverts to groupID initializer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-28 11:54:41 -06:00
parent 6ce7c508ed
commit 675547db76
3 changed files with 24 additions and 4 deletions

View File

@@ -56,7 +56,7 @@
"localizations" : [
{
"description" : "Unlock all features with monthly access.",
"displayName" : " Reflect Monthly",
"displayName" : "Reflect Monthly",
"locale" : "en_US"
},
{

View File

@@ -266,11 +266,17 @@ class IAPManager: ObservableObject {
// MARK: - Private Methods
private func loadProducts() async {
AppLogger.iap.info("loadProducts() called — requesting: \(Self.productIdentifiers.sorted().joined(separator: ", "))")
do {
let products = try await Product.products(for: Self.productIdentifiers)
AppLogger.iap.info("loadProducts() returned \(products.count) products total")
for product in products {
AppLogger.iap.info(" Product: \(product.id) — type: \(product.type.rawValue), displayName: \(product.displayName), price: \(product.displayPrice)")
}
availableProducts = products.filter { $0.type == .autoRenewable }
AppLogger.iap.info("loadProducts() filtered to \(self.availableProducts.count) autoRenewable products")
} catch {
AppLogger.iap.error("Failed to load products: \(error.localizedDescription)")
AppLogger.iap.error("loadProducts() FAILED: \(error.localizedDescription) — full error: \(String(describing: error))")
}
}

View File

@@ -7,6 +7,7 @@
import SwiftUI
import StoreKit
import os.log
struct ReflectSubscriptionStoreView: View {
@Environment(\.dismiss) private var dismiss
@@ -27,7 +28,7 @@ struct ReflectSubscriptionStoreView: View {
}
var body: some View {
SubscriptionStoreView(productIDs: IAPManager.productIdentifiers) {
SubscriptionStoreView(groupID: IAPManager.subscriptionGroupID) {
marketingContent
}
.subscriptionStoreControlStyle(.prominentPicker)
@@ -47,6 +48,19 @@ struct ReflectSubscriptionStoreView: View {
.accessibilityLabel("Close")
}
.onAppear {
AppLogger.iap.info("SubscriptionStoreView appeared — source: \(source), productIDs: \(IAPManager.productIdentifiers.sorted().joined(separator: ", ")), groupID: \(IAPManager.subscriptionGroupID)")
AppLogger.iap.info("IAPManager state — isLoading: \(iapManager.isLoading), products loaded: \(iapManager.availableProducts.count), state: \(String(describing: iapManager.state))")
// Also try loading products directly to log what StoreKit returns
Task {
do {
let products = try await Product.products(for: IAPManager.productIdentifiers)
AppLogger.iap.info("Direct Product.products() returned \(products.count) products: \(products.map { "\($0.id) (\($0.displayName))" }.joined(separator: ", "))")
} catch {
AppLogger.iap.error("Direct Product.products() FAILED: \(error.localizedDescription)")
}
}
AnalyticsManager.shared.trackPaywallViewed(source: source)
}
.onInAppPurchaseStart { product in
@@ -103,7 +117,7 @@ struct ReflectSubscriptionStoreView: View {
JournalMarketingContent()
}
}
.containerRelativeFrame(.horizontal)
.frame(maxWidth: .infinity)
}
private var tintColor: Color {