Jelajahi Sumber

Introduce SubscriptionType to differentiate between auto-renewable and non-renewing subscriptions.
For auto-renewable, receipt["latest_receipt_info"] is used.
For non-renewing, receipt["receipt"]?["in_app"] is used.

Andrea Bizzotto 8 tahun lalu
induk
melakukan
dafd0019be

+ 19 - 8
README.md

@@ -225,8 +225,8 @@ SwiftyStoreKit.verifyReceipt(using: appleValidator, password: "your-shared-secre
         // Verify the purchase of Consumable or NonConsumable
         let purchaseResult = SwiftyStoreKit.verifyPurchase(
             productId: "com.musevisions.SwiftyStoreKit.Purchase1",
-            inReceipt: receipt
-        )
+            inReceipt: receipt)
+            
         switch purchaseResult {
         case .purchased(let expiresDate):
             print("Product is purchased.")
@@ -250,11 +250,10 @@ SwiftyStoreKit.verifyReceipt(using: appleValidator, password: "your-shared-secre
     case .success(let receipt):
         // Verify the purchase of a Subscription
         let purchaseResult = SwiftyStoreKit.verifySubscription(
+            type: .autoRenewable, // or .nonRenewing (see below)
             productId: "com.musevisions.SwiftyStoreKit.Subscription",
-            inReceipt: receipt,
-            validUntil: NSDate(),
-            validDuration: 3600 * 24 * 30 // Non Renewing Subscription only
-        )
+            inReceipt: receipt)
+            
         switch purchaseResult {
         case .purchased(let expiresDate):
             print("Product is valid until \(expiresDate)")
@@ -270,9 +269,21 @@ SwiftyStoreKit.verifyReceipt(using: appleValidator, password: "your-shared-secre
 }
 ```
 
+#### Auto-Renewable
+```
+let purchaseResult = SwiftyStoreKit.verifySubscription(
+            type: .autoRenewable,
+            productId: "com.musevisions.SwiftyStoreKit.Subscription",
+            inReceipt: receipt)
+```
 
-To test the expiration of a Non Renewing Subscription, you must indicate the `validDuration` time interval in seconds.
-
+#### Non-Renewing
+```
+let purchaseResult = SwiftyStoreKit.verifySubscription(
+            type: .nonRenewing(validDuration: 3600 * 24 * 30),
+            productId: "com.musevisions.SwiftyStoreKit.Subscription",
+            inReceipt: receipt)
+```
 
 
 **NOTE**:

+ 12 - 3
SwiftyStoreKit-iOS-Demo/ViewController.swift

@@ -136,15 +136,24 @@ class ViewController: UIViewController {
 
                 let productId = self.appBundleId + "." + purchase.rawValue
 
-                // Specific behaviour for AutoRenewablePurchase
-                if purchase == .autoRenewablePurchase {
+                switch purchase {
+                case .autoRenewablePurchase:
                     let purchaseResult = SwiftyStoreKit.verifySubscription(
+                        type: .autoRenewable,
                         productId: productId,
                         inReceipt: receipt,
                         validUntil: Date()
                     )
                     self.showAlert(self.alertForVerifySubscription(purchaseResult))
-                } else {
+                case .nonRenewingPurchase:
+                    let purchaseResult = SwiftyStoreKit.verifySubscription(
+                        type: .nonRenewing(validDuration: 60),
+                        productId: productId,
+                        inReceipt: receipt,
+                        validUntil: Date()
+                    )
+                    self.showAlert(self.alertForVerifySubscription(purchaseResult))
+                default:
                     let purchaseResult = SwiftyStoreKit.verifyPurchase(
                         productId: productId,
                         inReceipt: receipt

+ 12 - 5
SwiftyStoreKit-macOS-Demo/ViewController.swift

@@ -131,15 +131,22 @@ class ViewController: NSViewController {
 
                 let productId = self.appBundleId + "." + purchase.rawValue
 
-                // Specific behaviour for AutoRenewablePurchase
-                if purchase == .autoRenewablePurchase {
+                switch purchase {
+                case .autoRenewablePurchase:
                     let purchaseResult = SwiftyStoreKit.verifySubscription(
+                        type: .autoRenewable,
                         productId: productId,
-                        inReceipt: receipt,
-                        validUntil: Date()
+                        inReceipt: receipt
+                    )
+                    self.showAlert(self.alertForVerifySubscription(purchaseResult))
+                case .nonRenewingPurchase:
+                    let purchaseResult = SwiftyStoreKit.verifySubscription(
+                        type: .nonRenewing(validDuration: 60),
+                        productId: productId,
+                        inReceipt: receipt
                     )
                     self.showAlert(self.alertForVerifySubscription(purchaseResult))
-                } else {
+                default:
                     let purchaseResult = SwiftyStoreKit.verifyPurchase(
                         productId: productId,
                         inReceipt: receipt

+ 13 - 3
SwiftyStoreKit/InAppReceipt.swift

@@ -86,6 +86,7 @@ internal class InAppReceipt {
 
     /**
      *  Verify the purchase of a subscription (auto-renewable, free or non-renewing) in a receipt. This method extracts all transactions mathing the given productId and sorts them by date in descending order, then compares the first transaction expiry date against the validUntil value.
+     *  - parameter type: .autoRenewable or .nonRenewing(duration)
      *  - Parameter productId: the product id of the purchase to verify
      *  - Parameter inReceipt: the receipt to use for looking up the subscription
      *  - Parameter validUntil: date to check against the expiry date of the subscription. If nil, no verification
@@ -93,16 +94,16 @@ internal class InAppReceipt {
      *  - return: either NotPurchased or Purchased / Expired with the expiry date found in the receipt
      */
     class func verifySubscription(
+        type: SubscriptionType,
         productId: String,
         inReceipt receipt: ReceiptInfo,
-        validUntil date: Date = Date(),
-        validDuration duration: TimeInterval? = nil
+        validUntil date: Date = Date()
     ) -> VerifySubscriptionResult {
 
         // Verify that at least one receipt has the right product id
 
         // The values of the latest_receipt and latest_receipt_info keys are useful when checking whether an auto-renewable subscription is currently active. By providing any transaction receipt for the subscription and checking these values, you can get information about the currently-active subscription period. If the receipt being validated is for the latest renewal, the value for latest_receipt is the same as receipt-data (in the request) and the value for latest_receipt_info is the same as receipt.
-        let receipts = receipt["latest_receipt_info"] as? [ReceiptInfo]
+        let (receipts, duration) = getReceiptsAndDuration(for: type, inReceipt: receipt)
         let receiptsInfo = filterReceiptsInfo(receipts: receipts, withProductId: productId)
         if receiptsInfo.count == 0 {
             return .notPurchased
@@ -143,6 +144,15 @@ internal class InAppReceipt {
         }
     }
 
+    private class func getReceiptsAndDuration(for subscriptionType: SubscriptionType, inReceipt receipt: ReceiptInfo) -> ([ReceiptInfo]?, TimeInterval?) {
+        switch subscriptionType {
+        case .autoRenewable:
+            return (receipt["latest_receipt_info"] as? [ReceiptInfo], nil)
+        case .nonRenewing(let duration):
+            return (receipt["receipt"]?["in_app"] as? [ReceiptInfo], duration)
+        }
+    }
+
     private class func getReceiptRequestDate(inReceipt receipt: ReceiptInfo) -> Date? {
 
         guard let receiptInfo = receipt["receipt"] as? ReceiptInfo,

+ 5 - 0
SwiftyStoreKit/SwiftyStoreKit+Types.swift

@@ -96,6 +96,11 @@ public enum VerifySubscriptionResult {
     case notPurchased
 }
 
+public enum SubscriptionType {
+    case autoRenewable
+    case nonRenewing(validDuration: TimeInterval)
+}
+
 // Error when managing receipt
 public enum ReceiptError: Swift.Error {
     // No receipt data

+ 3 - 3
SwiftyStoreKit/SwiftyStoreKit.swift

@@ -250,11 +250,11 @@ extension SwiftyStoreKit {
      *  - return: either NotPurchased or Purchased / Expired with the expiry date found in the receipt
      */
     public class func verifySubscription(
+        type: SubscriptionType,
         productId: String,
         inReceipt receipt: ReceiptInfo,
-        validUntil date: Date = Date(),
-        validDuration duration: TimeInterval? = nil
+        validUntil date: Date = Date()
         ) -> VerifySubscriptionResult {
-        return InAppReceipt.verifySubscription(productId: productId, inReceipt: receipt, validUntil: date, validDuration: duration)
+        return InAppReceipt.verifySubscription(type: type, productId: productId, inReceipt: receipt, validUntil: date)
     }
 }