使用 SwiftyStoreKit 自动更新

问题描述

SwiftyStoreKit 对我来说是一个非常困难的产品,因为将近一周,我在 StackOverflow、YouTube 和 Google 上到处搜索答案。我找不到任何答案,因为我正在研究 Auto-Renewable,我试图找出用户是否取消订阅或过期,应用程序会要求重新订阅。在测试期间,购买效果很好,但我需要弄清楚应用程序如何知道订阅是否已过期。每次我尝试验证时,我的验证收据总是返回以下错误消息。我做错了什么?

Receipt verification Failed: receiptInvalid(receipt: ["status": 21002],status: SwiftyStoreKit.ReceiptStatus.malformedOrMissingData)

这是我的顶级代码

import SwiftyStoreKit

var sharedSecret = " * My shared Secret * "
let appleValidator = AppleReceiptValidator(service: .sandBox,sharedSecret: sharedSecret)

enum RegisteredPurchase: String {
    case autoRenewable = " * My Auto-Renewable Bundle ID * "
}

购买时带有按钮的代码

@objc func startSub() {
   StoreManager.shared.purchase(purchase: RegisteredPurchase.autoRenewable)
}

AppDelegate.swift

SwiftyStoreKit.completeTransactions(atomically: true) { purchaseStatus in
   for products in purchaseStatus {
      switch products.transaction.transactionState {
      case .purchased,.restored:
         if products.needsFinishTransaction {
            SwiftyStoreKit.finishTransaction(products.transaction)
         }
      default: break
      }
   }
}

SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
   switch result {
   case .success(let receipt):
      let productID = Set([RegisteredPurchase.autoRenewable.rawValue])
      let purchaseResult = SwiftyStoreKit.verifySubscriptions(productIds: productID,inReceipt: receipt)
      switch purchaseResult {
      case .purchased(let expiryDate,let items):
         print("\(productID) are valid until \(expiryDate),\(items).")
      case .expired(let expiryDate,let items):
         print("\(productID) are expired since \(expiryDate),\(items).")
      case .notPurchased:
         print("The product has never purchased...")
      }
   case .error(let error):
      print("Receipt verification Failed: \(error)")
   }
}

StoreKitManager.swift

class StoreManager: NSObject {
   @objc static let shared = StoreManager()

   func getInfo(purchase: RegisteredPurchase) {
      SwiftyStoreKit.retrieveProductsInfo([purchase.rawValue],completion: { result in
         if result.error == nil {
            for x in result.retrievedProducts {
               print("Get information: \(x.localizedTitle)")
            }
         } else {
             print("Error getting information")
         }
      })
   }

   func purchase(purchase: RegisteredPurchase) {
      SwiftyStoreKit.purchaseProduct(purchase.rawValue,completion: { result in
          if case .success(let product) = result {
              if product.needsFinishTransaction {
                  SwiftyStoreKit.finishTransaction(product.transaction)
              }
              print("Purchasing: \(result)")
              self.purchaseResult(result: result)
          }
      })
   }

    
   func verifyReceipt() {
       SwiftyStoreKit.verifyReceipt(using: appleValidator,completion: { result in
           self.verifyReceipt(result: result)
           if case .error(let error) = result {
               if case .noreceiptData = error {
                   self.refreshReceipt()
               }
           }
       })
   }
    
   func verifyPurchase(product: RegisteredPurchase) {
       SwiftyStoreKit.verifyReceipt(using: appleValidator,completion: { result in
           switch result {
           case .success(let receipt):
               let productID = RegisteredPurchase.autoRenewable
               if product == .autoRenewable {
                   let purchseResult = SwiftyStoreKit.verifySubscription(ofType: .autoRenewable,productId: productID.rawValue,inReceipt: receipt,validUntil: Date())
                   print("Verify Purchase Result: \(purchseResult)")
               }
           case .error(let error):
               print("Error verify purchase: \(error)")
               if case .noreceiptData = error {
                   self.refreshReceipt()
               }
           }
       })
   }
   
   func refreshReceipt() {
       SwiftyStoreKit.fetchReceipt(forceRefresh: true,completion: { result in
           print("Start refreshing the receipt...")
       })
   }
   
   func purchaseResult(result: PurchaseResult) {
       switch result {
       case .success(let product):
           print("Purchase Successful: \(product.productId)")
       case .error(let error):
           print("Purchase Failed: \(error)")
       }
   }
   
   func restoreResult(result: RestoreResults) {
       if result.restoreFailedPurchases.count > 0 {
           print("Restore Failed by unkNown error")
       } else if result.restoredPurchases.count > 0 {
           print("Restore Successful")
       } else {
           print("nothing to Restore.")
       }
   }
   
   func verifyReceipt(result: VerifyReceiptResult) {
       switch result {
       case .success(let receipt): return print("Verify Receipt: \(receipt)")
       case .error(let error):
           switch error {
           case .noremoteData: return print("No receipt founded. Try again")
           default: return print("Error Verify Receipt: \(error)")
           }
       }
   }
   
   func verifySubscription(result: VerifySubscriptionResult) {
       switch result {
       case .purchased(let expiryDate):
           print("Product is purchased,valid until \(expiryDate)")
       case .notPurchased:
           print("Product has never purchased.")
       case .expired(let expiredDate):
           print("The product is expired since \(expiredDate)!")
       }
   }
   
   func verifyPurchase(result: VerifyPurchaseResult) {
       switch result {
       case .purchased: print("Product is purchased,will not expired.")
       case .notPurchased: print("Product is not purchased,has never been purchased.")
       }
   }
   
   func refreshReceipt(result: FetchReceiptResult) {
      switch result {
      case .success(let receiptData): print("Receipt Refreshed,\(receiptData)")
      case .error(let receiptData): print("Receipt not Refresh,\(receiptData)")
      }
   }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...