ios - 触摸 "buy"后应用内购买失败

标签 ios swift in-app-purchase

我发现这段代码可以在 iOS 9 上使用 swift 2 执行应用内购买。 我的 IAP(应用内购买)将位于表格中。它将显示为一条提醒消息,您可以在其中点击购买取消。 如果您点击购买,则会显示来自 Appstore 的新提醒以确认这一点。

我使用沙盒用户登录。确认后,我的控制台显示:

Transaction Failed

代码如下:

import UIKit
import StoreKit
import iAd

protocol IAPurchaceViewControllerDelegate {

    func didBuyPremium(Index: Int)

}

class iAP: UIViewController, UITableViewDelegate, UITableViewDataSource, SKProductsRequestDelegate, SKPaymentTransactionObserver {




    @IBOutlet weak var LoadingScreen: UIView!



        @IBOutlet weak var tblProducts: UITableView!

        var delegate: IAPurchaceViewControllerDelegate!

        var productIDs: Array<String!> = []

        var productsArray: Array<SKProduct!> = []

        var selectedProductIndex: Int!

        var transactionInProgress = false


    override func viewWillAppear(animated: Bool) {
        view.bringSubviewToFront(LoadingScreen)
        LoadingScreen.hidden = false
        navigationController?.setNavigationBarHidden(false, animated: true)
    }

        override func viewDidLoad() {
            super.viewDidLoad()

            // Do any additional setup after loading the view.

            tblProducts.delegate = self
            tblProducts.dataSource = self


            // Replace the product IDs with your own values if needed.
            productIDs.append("xxx_Iap")
            requestProductInfo()

            SKPaymentQueue.defaultQueue().addTransactionObserver(self)
        }



        // MARK: UITableView method implementation

        func numberOfSectionsInTableView(tableView: UITableView) -> Int {
            return 1
        }


        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return productsArray.count
        }


    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 65
    }


        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

            let cell = tableView.dequeueReusableCellWithIdentifier("IAPCell") as! ModifyCellsIAP


            let product = productsArray[indexPath.row]
            cell.PremiumName.text = product.localizedTitle
            cell.PremiumBeschreibung.text = product.localizedDescription

            let price = "\(product.price)"
            let FormatPrice = price.stringByReplacingOccurrencesOfString(".", withString: ",")
            cell.PremiumPreis.setTitle("\(FormatPrice)€", forState: .Normal)

            LoadingScreen.hidden = true
            return cell
        }


        func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            selectedProductIndex = indexPath.row
            showActions()
            tableView.cellForRowAtIndexPath(indexPath)?.selected = false
        }




        func requestProductInfo() {
            if SKPaymentQueue.canMakePayments() {
                let productIdentifiers = NSSet(array: productIDs)
                let productRequest:SKProductsRequest = SKProductsRequest(productIdentifiers: productIdentifiers as! Set<String>)

                productRequest.delegate = self
                productRequest.start()
            }
            else {
                print("Cannot perform In App Purchases.")
            }
        }


        func showActions() {
            if transactionInProgress {
                return
            }

            let actionSheetController = UIAlertController(title: "Upgrade", message: "Möchten Sie diese Erweiterung freischalten?", preferredStyle: UIAlertControllerStyle.ActionSheet)

            let buyAction = UIAlertAction(title: "Freischalten", style: UIAlertActionStyle.Default) { (action) -> Void in
                let payment = SKPayment(product: self.productsArray[self.selectedProductIndex] as SKProduct)
                SKPaymentQueue.defaultQueue().addPayment(payment)
                self.transactionInProgress = true
            }

            let cancelAction = UIAlertAction(title: "Abbrechen", style: UIAlertActionStyle.Cancel) { (action) -> Void in

            }

            actionSheetController.addAction(buyAction)
            actionSheetController.addAction(cancelAction)

            presentViewController(actionSheetController, animated: true, completion: nil)
        }



        func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
            if response.products.count != 0 {
                for product in response.products {
                    productsArray.append(product )
                }

                tblProducts.reloadData()
            }
            else {
                print("There are no products.")
            }

            if response.invalidProductIdentifiers.count != 0 {
                print("Invalid: \(response.invalidProductIdentifiers.description)")
            }
        }



        func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
            for transaction in transactions {
                switch transaction.transactionState {
                case SKPaymentTransactionState.Purchased:
                    print("Transaction completed successfully.")
                    SKPaymentQueue.defaultQueue().finishTransaction(transaction)
                    transactionInProgress = false
                    delegate.didBuyPremium(selectedProductIndex)


                case SKPaymentTransactionState.Failed:
                    print("Transaction Failed");
                    SKPaymentQueue.defaultQueue().finishTransaction(transaction)
                    transactionInProgress = false

                default:
                    print("Default: \(transaction.transactionState.rawValue)")
                }
            }
        }




}

最佳答案

我最近在我的应用中成功实现了应用内购买。乐于分享经验。 Objective-C 中的代码,但我相信这不应该有任何根本的区别。

要检查的事情:

  1. 检查应用内购买是否可用:

    if ([SKPaymentQueue canMakePayments] == YES) {
        // proceed with payment
    }
    
  2. 交易失败错误代码:

    if (transaction.error.code != SKErrorPaymentCancelled) {
        // This is the error that should be presented to user and/or processed
    }
    else {
       // "Canceled" error should go silently for user as this is more or less expected.
       // The user can re-issue the payment process later on
    }
    

关于ios - 触摸 "buy"后应用内购买失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32623769/

相关文章:

ios - 根据动态文本设置 UITextView 的宽度和高度

iOS 应用内购买 - 使用超时是否明智?

iPhone 显示旧版本的应用程序

ios - 将 UISearchBar returnKeyType 更改为 Done 在 iPhone 5 上有效,但在 iPhone 4s 上会使应用程序崩溃

ios - 为什么 Swift 方法只需要第二个输入的标签?

ios - NSNotificationCenter 在应用程序购买期间发送释放的消息

ios - 在没有付费苹果开发者帐户的情况下在 swift 中使用应用内购买

ios - 添加 subview 时标题 View 消失?

ios - 内存泄漏,即使每个 alloc 都已释放

ios - 如何使用选项卡栏管理容器 View 中的 Controller