Bladeren bron

fix(iap): stop showing hardcoded paywall prices before StoreKit loads

Use localized Product.displayPrice only; show an em dash until products are available.
Document ASC-safe product ID rules and keeping IDs in sync across code and StoreKit config.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 2 maanden geleden
bovenliggende
commit
3c71d5b75e

+ 9 - 7
App for Indeed/Controllers/PremiumPlansWindowController.swift

@@ -356,11 +356,13 @@ private final class PremiumPlansViewController: NSViewController {
         }
     }
 
+    /// Shown until StoreKit returns localized `Product.displayPrice` (never use hardcoded currency amounts).
+    private static let unloadedPricePlaceholder = "—"
+
     private struct Plan {
         let id: String
         let title: String
         let subtitle: String
-        let price: String
         let period: String
         let billedPill: String
         let billedLine: String
@@ -405,7 +407,6 @@ private final class PremiumPlansViewController: NSViewController {
             id: "weekly",
             title: "Weekly",
             subtitle: "Flexible and commitment-free",
-            price: "$9.99",
             period: "/ week",
             billedPill: "",
             billedLine: "",
@@ -424,7 +425,6 @@ private final class PremiumPlansViewController: NSViewController {
             id: "monthly",
             title: "Monthly",
             subtitle: "Balanced for regular productivity",
-            price: "$19.99",
             period: "/ month",
             billedPill: "",
             billedLine: "",
@@ -443,7 +443,6 @@ private final class PremiumPlansViewController: NSViewController {
             id: "yearly",
             title: "Yearly",
             subtitle: "Best value for long-term users",
-            price: "$39.99",
             period: "/ year",
             billedPill: "3 days free trial",
             billedLine: "",
@@ -603,7 +602,7 @@ private final class PremiumPlansViewController: NSViewController {
         topRightTag.isHidden = plan.billedPill.isEmpty
         topRightTag.font = .systemFont(ofSize: 10, weight: .bold)
 
-        let priceLabel = NSTextField(labelWithString: plan.price)
+        let priceLabel = NSTextField(labelWithString: Self.unloadedPricePlaceholder)
         priceLabel.font = .systemFont(ofSize: 18, weight: .semibold)
         priceLabel.textColor = Theme.primaryText
 
@@ -931,8 +930,11 @@ private final class PremiumPlansViewController: NSViewController {
 
     private func applyStorePricing() {
         for plan in plans {
-            guard let fields = planPriceFields[plan.id],
-                  let product = subscriptionStore.product(forPlanKey: plan.id) else { continue }
+            guard let fields = planPriceFields[plan.id] else { continue }
+            guard let product = subscriptionStore.product(forPlanKey: plan.id) else {
+                fields.price.stringValue = Self.unloadedPricePlaceholder
+                continue
+            }
             fields.price.stringValue = product.displayPrice
             if let period = product.subscription?.subscriptionPeriod {
                 fields.period.stringValue = periodSuffix(for: period)

+ 3 - 2
App for Indeed/Subscription/SubscriptionProductIDs.swift

@@ -6,8 +6,9 @@
 import Foundation
 
 /// Identifiers for auto-renewable subscriptions in App Store Connect.
-/// Local Xcode runs use `App for Indeed/ProSubscriptions.storekit` (selected in the Run scheme → Options → StoreKit Configuration).
-/// Create three subscriptions with these exact IDs and attach them to the same subscription group.
+/// IDs may only contain letters, numbers, underscores, and periods (no hyphens).
+/// Keep these strings identical in code, `ProSubscriptions.storekit`, and App Store Connect.
+/// Local Xcode runs use `App for Indeed/ProSubscriptions.storekit` (Run scheme → Options → StoreKit Configuration).
 enum SubscriptionProductIDs {
     static let weekly = "com.mqldev.appforindeed.pro.weekly"
     static let monthly = "com.mqldev.appforindeed.pro.monthly"