Sfoglia il codice sorgente

Fix StoreKit subscription configuration and premium upgrade behavior.

Move recurring plans into a proper subscription group for StoreKit testing, route lifetime users to subscription management from the sidebar, and add a lifetime-upgrade warning to cancel existing subscriptions to avoid renewal charges.

Made-with: Cursor
huzaifahayat12 3 mesi fa
parent
commit
1b757d6d2b
2 ha cambiato i file con 86 aggiunte e 54 eliminazioni
  1. 72 46
      meetings_app/StoreKit.storekit
  2. 14 8
      meetings_app/ViewController.swift

+ 72 - 46
meetings_app/StoreKit.storekit

@@ -2,51 +2,6 @@
   "identifier" : "7B5DA685-94A9-4A9B-86EA-F7D90A0D5249",
   "nonRenewingSubscriptions" : [],
   "products" : [
-    {
-      "displayPrice" : "1100.00",
-      "familyShareable" : false,
-      "internalID" : "F16C0A1F-5B83-41AB-A9F2-69157A11A11A",
-      "localizations" : [
-        {
-          "description" : "Unlock premium features with weekly access.",
-          "displayName" : "Premium Weekly",
-          "locale" : "en_US"
-        }
-      ],
-      "productID" : "com.mqldev.meetingsapp.premium.weekly",
-      "referenceName" : "Premium Weekly",
-      "type" : "NonConsumable"
-    },
-    {
-      "displayPrice" : "2500.00",
-      "familyShareable" : false,
-      "internalID" : "B2B57D59-AE2B-4953-BF03-5D4AFECAC6C1",
-      "localizations" : [
-        {
-          "description" : "Unlock premium features with monthly access.",
-          "displayName" : "Premium Monthly",
-          "locale" : "en_US"
-        }
-      ],
-      "productID" : "com.mqldev.meetingsapp.premium.monthly",
-      "referenceName" : "Premium Monthly",
-      "type" : "NonConsumable"
-    },
-    {
-      "displayPrice" : "9900.00",
-      "familyShareable" : false,
-      "internalID" : "C5694F51-47D8-4AFD-9D33-95A888527BB5",
-      "localizations" : [
-        {
-          "description" : "Unlock premium features with yearly access.",
-          "displayName" : "Premium Yearly",
-          "locale" : "en_US"
-        }
-      ],
-      "productID" : "com.mqldev.meetingsapp.premium.yearly",
-      "referenceName" : "Premium Yearly",
-      "type" : "NonConsumable"
-    },
     {
       "displayPrice" : "14900.00",
       "familyShareable" : false,
@@ -74,7 +29,78 @@
     "_storefront" : "PAK",
     "_timeRate" : 0
   },
-  "subscriptionGroups" : [],
+  "subscriptionGroups" : [
+    {
+      "id" : "A2D0B1D6",
+      "localizations" : [],
+      "name" : "Premium",
+      "subscriptions" : [
+        {
+          "adHocOffers" : [],
+          "codeOffers" : [],
+          "displayPrice" : "1100.00",
+          "familyShareable" : false,
+          "groupNumber" : 3,
+          "internalID" : "F16C0A1F-5B83-41AB-A9F2-69157A11A11A",
+          "introductoryOffer" : null,
+          "localizations" : [
+            {
+              "description" : "Unlock premium features with weekly access.",
+              "displayName" : "Premium Weekly",
+              "locale" : "en_US"
+            }
+          ],
+          "productID" : "com.mqldev.meetingsapp.premium.weekly",
+          "recurringSubscriptionPeriod" : "P1W",
+          "referenceName" : "Premium Weekly",
+          "subscriptionGroupID" : "A2D0B1D6",
+          "type" : "RecurringSubscription"
+        },
+        {
+          "adHocOffers" : [],
+          "codeOffers" : [],
+          "displayPrice" : "2500.00",
+          "familyShareable" : false,
+          "groupNumber" : 2,
+          "internalID" : "B2B57D59-AE2B-4953-BF03-5D4AFECAC6C1",
+          "introductoryOffer" : null,
+          "localizations" : [
+            {
+              "description" : "Unlock premium features with monthly access.",
+              "displayName" : "Premium Monthly",
+              "locale" : "en_US"
+            }
+          ],
+          "productID" : "com.mqldev.meetingsapp.premium.monthly",
+          "recurringSubscriptionPeriod" : "P1M",
+          "referenceName" : "Premium Monthly",
+          "subscriptionGroupID" : "A2D0B1D6",
+          "type" : "RecurringSubscription"
+        },
+        {
+          "adHocOffers" : [],
+          "codeOffers" : [],
+          "displayPrice" : "9900.00",
+          "familyShareable" : false,
+          "groupNumber" : 1,
+          "internalID" : "C5694F51-47D8-4AFD-9D33-95A888527BB5",
+          "introductoryOffer" : null,
+          "localizations" : [
+            {
+              "description" : "Unlock premium features with yearly access.",
+              "displayName" : "Premium Yearly",
+              "locale" : "en_US"
+            }
+          ],
+          "productID" : "com.mqldev.meetingsapp.premium.yearly",
+          "recurringSubscriptionPeriod" : "P1Y",
+          "referenceName" : "Premium Yearly",
+          "subscriptionGroupID" : "A2D0B1D6",
+          "type" : "RecurringSubscription"
+        }
+      ]
+    }
+  ],
   "version" : {
     "major" : 3,
     "minor" : 0

+ 14 - 8
meetings_app/ViewController.swift

@@ -550,7 +550,9 @@ private extension ViewController {
     }
 
     @objc private func premiumButtonClicked(_ sender: NSClickGestureRecognizer) {
-        if storeKitCoordinator.hasPremiumAccess {
+        if storeKitCoordinator.hasLifetimeAccess {
+            openManageSubscriptions()
+        } else if storeKitCoordinator.hasPremiumAccess {
             showPaywall(upgradeFlow: true, preferredPlan: .lifetime)
         } else {
             showPaywall()
@@ -1022,10 +1024,15 @@ private extension ViewController {
         DispatchQueue.main.asyncAfter(deadline: .now() + 2.0, execute: hideWorkItem)
     }
 
-    private func confirmPremiumUpgrade() -> Bool {
+    private func confirmPremiumUpgrade(for targetPlan: PremiumPlan) -> Bool {
         let alert = NSAlert()
-        alert.messageText = "Already Premium"
-        alert.informativeText = "You are already premium. Do you want to continue with this purchase?"
+        if targetPlan == .lifetime, storeKitCoordinator.hasPremiumAccess, !storeKitCoordinator.hasLifetimeAccess {
+            alert.messageText = "Switching to Lifetime"
+            alert.informativeText = "You already have an active subscription. If you buy Lifetime, cancel your current subscription in App Store Subscriptions to avoid future renewal charges."
+        } else {
+            alert.messageText = "Already Premium"
+            alert.informativeText = "You are already premium. Do you want to continue with this purchase?"
+        }
         alert.addButton(withTitle: "Continue")
         alert.addButton(withTitle: "Cancel")
         return alert.runModal() == .alertFirstButtonReturn
@@ -1294,9 +1301,8 @@ private extension ViewController {
             let productID = PremiumStoreProduct.productID(for: plan)
             guard let product = storeKitCoordinator.productsByID[productID],
                   let period = product.subscription?.subscriptionPeriod else {
-                if plan == .monthly {
-                    label.stringValue = "3 days free trial"
-                }
+                // Show neutral fallback text when subscription metadata isn't available.
+                label.stringValue = "Billed via App Store"
                 continue
             }
             let recurringText = "\(pkrDisplayPrice(product.displayPrice))/\(subscriptionUnitText(period.unit))"
@@ -1525,7 +1531,7 @@ private extension ViewController {
             }
             return
         }
-        if paywallUpgradeFlowEnabled && storeKitCoordinator.hasPremiumAccess && !confirmPremiumUpgrade() {
+        if paywallUpgradeFlowEnabled && storeKitCoordinator.hasPremiumAccess && !confirmPremiumUpgrade(for: selectedPremiumPlan) {
             return
         }
         paywallPurchaseTask?.cancel()