我在我的OS X应用程序中购买了一个耗材应用内购买了一定数量的硬币 . 但是,第二次购买消耗品时,我收到一条警告,说该物品已经购买并将免费恢复 .

为什么会发生消费类应用内购买?

这是我的IAP代码:

typealias RequestProductsCompletionHandler = ([SKProduct]?) -> Void

class IAPHelper: NSObject, SKProductsRequestDelegate{

    private var productsRequest: SKProductsRequest?
    private var completionHandler: RequestProductsCompletionHandler!
    private let productIdentifiers: Set<String>
    private var purchasedProductIdentifiers = Set<String>()

    init(productIdentifiers: Set<String>){
        self.productIdentifiers = productIdentifiers
        super.init()
        for identifier in productIdentifiers{
            let productPurchased = NSUserDefaults.standardUserDefaults().boolForKey(identifier)
            if productPurchased{
                purchasedProductIdentifiers.insert(identifier)
            }
        }
    }

    func requestProducts(completionHandler: RequestProductsCompletionHandler){
        self.completionHandler = completionHandler
        productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
        productsRequest?.delegate = self
        productsRequest?.start()
    }

    // MARK: SKProductsRequestDelegate

    func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
        productsRequest = nil
        let skProducts = response.products as! [SKProduct]
        completionHandler(skProducts)
        completionHandler = nil
    }

    func request(request: SKRequest, didFailWithError error: NSError) {
        productsRequest = nil
        print("Error: \(error)\nDescription: \(error.description)")
        completionHandler(nil)
        completionHandler = nil
    }

    func buyProduct(product: SKProduct){
        let payment = SKPayment.paymentWithProduct(product) as! SKPayment
        SKPaymentQueue.defaultQueue().addTransactionObserver(self)
        SKPaymentQueue.defaultQueue().addPayment(payment)
    }

    func productPurchased(productIdentifier: String) -> Bool{
        return purchasedProductIdentifiers.contains(productIdentifier)
    }
}

extension IAPHelper: SKPaymentTransactionObserver{
    func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {
        for transaction in transactions as! [SKPaymentTransaction]{
            switch transaction.transactionState{
            case SKPaymentTransactionStatePurchased:
                completeTransaction(transaction)
            case SKPaymentTransactionStateFailed:
                failedTransaction(transaction)
            default:
                break
            }
        }
    }

    func completeTransaction(transaction: SKPaymentTransaction){
        provideContentForProductIdentifier(transaction.payment.productIdentifier)
        SKPaymentQueue.defaultQueue().finishTransaction(transaction)
    }

    func failedTransaction(transaction: SKPaymentTransaction){
        if let errorCode = transaction.error?.code where errorCode != SKErrorPaymentCancelled{
            print(transaction.error!.localizedDescription)
        }
        SKPaymentQueue.defaultQueue().finishTransaction(transaction)
    }

    func provideContentForProductIdentifier(productIdentifier: String){
        //Override in subclass
    }
}