在我的实时应用程序上,用户不断遇到消耗品错误。这是非常随机的错误,很少发生。
此应用内购买已被购买。它将免费恢复。
在我的应用中,除非应用购买过程完成,否则我无法阻止用户点击“立即购买”按钮。
我已经阅读了以下问题的解决方案
Sandbox trying to restore consumable IAP
My IAP isn't working. Bugs at func Paymentqueue
我在代码中的两个位置都有SKPaymentQueue.default()。add(),如下所示。我还为每个transactionState调用SKPaymentQueue.default()。finishTransaction(transaction)。
任何人都可以让我知道解决此问题还需要检查什么吗?
open class IAPHelper: NSObject {
// Callback
var purchaseStatusBlock: ((IAPHandlerAlertType, String, NSData) -> Void)?
var purchaseFailed: ((SKPaymentTransaction) -> Void)?
private let productIdentifiers: Set<ProductIdentifier>
private var productsRequest: SKProductsRequest?
private var productsRequestCompletionHandler: ProductsRequestCompletionHandler?
public init(productIds: Set<ProductIdentifier>) {
productIdentifiers = productIds
super.init()
SKPaymentQueue.default().add(self) // #1
}
}
第二个是
extension 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, vc: UIViewController) {
let viewController = vc as! PurchaseViewController
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment) // #2
}
}
交易
extension 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) {
deliverPurchaseNotificationFor(identifier: transaction.payment.productIdentifier)
let receiptURL = Bundle.main.appStoreReceiptURL
let receipt = NSData(contentsOf: receiptURL!)
if (receipt == nil) {
// No local receipt -- handle the error
let alert = UIAlertController(title: "Purchase Error", message: "No local receipt", preferredStyle: UIAlertController.Style.alert)
let okAction = UIAlertAction(title: "Ok", style: UIAlertAction.Style.default) { (action) in
}
alert.addAction(okAction)
return
}
// Callback
purchaseStatusBlock?(.purchased, transaction.payment.productIdentifier, receipt!)
SKPaymentQueue.default().finishTransaction(transaction)
}
private func fail(transaction: SKPaymentTransaction) {
if let transactionError = transaction.error as NSError?,
let localizedDescription = transaction.error?.localizedDescription,
transactionError.code != SKError.paymentCancelled.rawValue {
}
// Callback
purchaseFailed?(transaction)
SKPaymentQueue.default().finishTransaction(transaction)
}
private func restore(transaction: SKPaymentTransaction) {
guard let productIdentifier = transaction.original?.payment.productIdentifier else { return }
deliverPurchaseNotificationFor(identifier: productIdentifier)
SKPaymentQueue.default().finishTransaction(transaction)
}
private func deliverPurchaseNotificationFor(identifier: String?) {
guard let identifier = identifier else { return }
// purchasedProductIdentifiers.insert(identifier)
// UserDefaults.standard.set(true, forKey: identifier)
NotificationCenter.default.post(name: .IAPHelperPurchaseNotification, object: identifier)
}
}
答案 0 :(得分:0)
我们有一个类似的问题困扰了我们很长时间...
当用户发起购买交易,然后在完全处理交易之前失去互联网连接或终止了该应用程序时,将向他们收费,但即使恢复后也不会收到IAP内容
跟随Apple's best practices,并在应用启动时添加交易观察者
您应该删除:
SKPaymentQueue.default().add(self) // #1
通过您的IAPHelper.init
方法。
并在AppDelegate
中添加观察者:
class AppDelegate: UIResponder, UIApplicationDelegate {
let iapHelper = IAPHelper()
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
SKPaymentQueue.default().add(iapHelper)
}
然后在需要的ViewController中,可以使用以下命令访问iapHelper
:
let iapHelper = (UIApplication.shared.delegate as! AppDelegate).iapHelper