SwiftyStoreKit对我来说是一个非常困难的产品,因为几乎一个星期以来,我在StackOverflow,YouTube和谷歌上到处搜索答案。我找不到任何答案,因为我正在研究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)")
}
}
}发布于 2021-09-10 09:15:53
我刚接触StoreKit,但这是我的2分钱。该错误消息表明您的服务器可能无法接收有效数据。
以下是苹果公司的说法。
不要从你的应用调用应用商店服务器verifyReceipt终结点。你不能直接在用户的设备和App Store之间建立可信连接,因为你不能控制连接的任何一端,这使得它很容易受到中间机攻击。
https://stackoverflow.com/questions/68205503
复制相似问题