我跟着tuto https://www.raywenderlich.com/122144/in-app-purchase-tutorial
我发现了一种优雅的方法.
这是我的StoreKit助手:
import StoreKitpublic typealias ProductIDentifIEr = Stringpublic typealias ProductsRequestCompletionHandler = (_ success: Bool,_ products: [SKProduct]?) -> ()open class IAPHelper : NSObject { fileprivate let productIDentifIErs: Set<ProductIDentifIEr> fileprivate var purchasedProductIDentifIErs: Set<ProductIDentifIEr> = Set() fileprivate var productsRequest: SKProductsRequest? fileprivate var productsRequestCompletionHandler: ProductsRequestCompletionHandler? static let IAPHelperPurchaseNotification = "IAPHelperPurchaseNotification" public init(productIDs: Set<ProductIDentifIEr>) { productIDentifIErs = productIDs super.init() SKPaymentQueue.default().add(self) }}// MARK: - StoreKit APIextension IAPHelper { public func requestProducts(_ completionHandler: @escaPing ProductsRequestCompletionHandler) { productsRequest?.cancel() productsRequestCompletionHandler = completionHandler productsRequest = SKProductsRequest(productIDentifIErs: productIDentifIErs) productsRequest!.delegate = self productsRequest!.start() } public func buyProduct(_ product: SKProduct) { print("Buying \(product.productIDentifIEr)...") let payment = SKPayment(product: product) SKPaymentQueue.default().add(payment) } public func isProductPurchased(_ productIDentifIEr: ProductIDentifIEr) -> Bool { return purchasedProductIDentifIErs.contains(productIDentifIEr) } public class func canMakePayments() -> Bool { return SKPaymentQueue.canMakePayments() } public func restorePurchases() { SKPaymentQueue.default().restoreCompletedTransactions() }}// MARK: - SKProductsRequestDelegateextension IAPHelper: SKProductsRequestDelegate { public func productsRequest(_ request: SKProductsRequest,dIDReceive response: SKProductsResponse) { print("Loaded List of products...") let products = response.products productsRequestCompletionHandler?(true,products) clearRequestAndHandler() for p in products { print("Found product: \(p.productIDentifIEr) \(p.localizedTitle) \(p.price.floatValue)") } } public func request(_ request: SKRequest,dIDFailWithError error: Error) { print("Failed to load List of products.") print("Error: \(error.localizedDescription)") productsRequestCompletionHandler?(false,nil) clearRequestAndHandler() } private func clearRequestAndHandler() { productsRequest = nil productsRequestCompletionHandler = nil }}// MARK: - SKPaymentTransactionObserverextension IAPHelper: SKPaymentTransactionObserver { public func paymentQueue(_ queue: SKPaymentQueue,updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { switch (transaction.transactionState) { case .purchased: complete(transaction: transaction) break case .Failed: fail(transaction: transaction) break case .restored: restore(transaction: transaction) break case .deferred: break case .purchasing: break } } } private func complete(transaction: SKPaymentTransaction) { print("complete...") valIDateReceipt() deliverPurchaseNotificationFor(IDentifIEr: transaction.payment.productIDentifIEr) SKPaymentQueue.default().finishTransaction(transaction) } private func restore(transaction: SKPaymentTransaction) { guard let productIDentifIEr = transaction.original?.payment.productIDentifIEr else { return } print("restore... \(productIDentifIEr)") deliverPurchaseNotificationFor(IDentifIEr: productIDentifIEr) SKPaymentQueue.default().finishTransaction(transaction) } private func fail(transaction: SKPaymentTransaction) { print("fail...") if let transactionError = transaction.error as? NSError { if transactionError.code != SKError.paymentCancelled.rawValue { print("Transaction Error: \(transaction.error?.localizedDescription)") } } SKPaymentQueue.default().finishTransaction(transaction) } private func deliverPurchaseNotificationFor(IDentifIEr: String?) { guard let IDentifIEr = IDentifIEr else { return } purchasedProductIDentifIErs.insert(IDentifIEr) UserDefaults.standard.set(true,forKey: IDentifIEr) UserDefaults.standard.synchronize() NotificationCenter.default.post(name: NSNotification.name(rawValue: IAPHelper.IAPHelperPurchaseNotification),object: IDentifIEr) }}
我可以买一次,然后自动恢复:
This in-app purchase has already been bought. It will be restored for
free
当我收到此消息时,不会调用任何IAPHelper方法.
我的iTunes显示它是耗材:
即使卸载仍在恢复购买的应用程序.
它真的看起来像一个苹果虫,因为我的第一次测试我可以购买2..3次没有这个消息.
如果它不是错误,我该如何防止这种情况?
解决方法 对于那些陷入这种愚蠢局面的人来说,这里有一些WA和解决方案:queue.finishTransaction(transaction)
重要信息:使用paymentQueue方法完成交易:
public func paymentQueue(_ queue: SKPaymentQueue,updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { switch (transaction.transactionState) { case .purchased: complete(transaction: transaction) queue.finishTransaction(transaction) break case .Failed: fail(transaction: transaction) queue.finishTransaction(transaction) break case .restored: restore(transaction: transaction) queue.finishTransaction(transaction) break case .deferred: break case .purchasing: break } }}
这样可以避免这种情况.
如果你已经坚持下去,这里是工作,只是为了测试目的!
for transaction in SKPaymentQueue.default().transactions { print(transaction) SKPaymentQueue.default().finishTransaction(transaction) }
您可以将其放在临时按钮上,并在一次测试时清除所有交易.
至少它今天救了我的命.
总结以上是内存溢出为你收集整理的ios – 自动恢复应用内购买耗材全部内容,希望文章能够帮你解决ios – 自动恢复应用内购买耗材所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)