微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 SwiftyStoreKit 自动更新

如何解决使用 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.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?