返回并再次转向视图控制器

时间:2016-03-01 20:52:19

标签: ios swift in-app-purchase

你好我有工作的应用程序,当用户点击购买限制视图控制器(第一次点击)用户买了一切都很好,但当用户回到主控制器再去购买限制视图控制器和用户点击购买IAP进行双重交易和用户还可以再次主控制器再次购买限制视图控制器点击购买IAP做三重交易..我怎样才能解决这个问题我的代码如下。

PaymentManager

import UIKit
import StoreKit

protocol PurchaseManagerDelegate
{
    func refreshList()
    func restoreCompleted()
    func transactionIsActive()
}

class PurchaseManager: NSObject
{
    var productsArray = [SKProduct]()
    var purchaseItemID = ""

    var getprice:NSDecimalNumber = 0.00

    var delegate: PurchaseManagerDelegate?

    var transactionProgress = false

    var productsLoadedNotification = "productsLoadedNotification"

    var appusername:String? = prefs.valueForKey("email") as! String!


    // MARK: - Load product methods

    func loadPaymentInfo()
    {
        requestProductInfo()
        SKPaymentQueue.defaultQueue().addTransactionObserver(self)
    }

    func requestProductInfo()
    {
        let productIDs = getProductIDs()

        if SKPaymentQueue.canMakePayments()
        {
            let productRequest = SKProductsRequest(productIdentifiers: productIDs)
            productRequest.delegate = self

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

    func getProductIDs() -> Set<String>
    {
        var result = Set<String>()

        if let path = NSBundle.mainBundle().pathForResource("PurchaseID", ofType: "plist")
        {
            if let items = NSArray(contentsOfFile: path)
            {
                for purchaseGroups in items
                {
                    if let array = purchaseGroups as? [String]
                    {
                        for purchaseID in array
                        {
                            result.insert(purchaseID)
                        }
                    }
                }
            }
        }

        return result
    }

    // MARK: - Purchase methods

    func buyProduct(productID: String)
    {
        if transactionProgress
        {
            self.delegate?.transactionIsActive()
            return
        }

        for product in productsArray
        {

            let payment:SKMutablePayment = SKMutablePayment(product: product)

            if (productID == product.productIdentifier)
            {
                purchaseItemID = product.productIdentifier

                getprice = product.price

                payment.applicationUsername = self.appusername!;

                SKPaymentQueue.defaultQueue().addPayment(payment)
                self.transactionProgress = true
            }
        }
    }

    func restorePurchases()
    {
        if transactionProgress
        {
            self.delegate?.transactionIsActive()
            return
        }
        transactionProgress = true
        SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
    }

    // MARK: - Functional methods

    func getProductTitle(productID: String) -> String?
    {
        for product in productsArray
        {
            if (productID == product.productIdentifier)
            {
                return product.localizedTitle
            }
        }

        return nil
    }



    func getProductPrice(productID: String) -> String?
    {
        for product in productsArray
        {
            if (productID == product.productIdentifier)
            {
                let numberFormatter = NSNumberFormatter()
                numberFormatter.formatterBehavior = .Behavior10_4
                numberFormatter.numberStyle = .CurrencyStyle
                numberFormatter.locale = product.priceLocale

                return numberFormatter.stringFromNumber(product.price)!
            }
        }

        return nil
    }

    func productsAreLoaded() -> Bool
    {
        if (productsArray.count > 0)
        {
            return true
        }
        else
        {
            return false
        }
    }


    func isProductBought(productID: String) -> Bool
    {

        if(productID == "com.blaSupport" || productID == "com.bla.Show"){

            return false

        }else{

            return false
        }
    }
}

// MARK: - Product request methods

extension PurchaseManager: SKProductsRequestDelegate
{
    func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse)
    {
        if response.products.count != 0
        {
            productsArray = response.products
        }

        if response.invalidProductIdentifiers.count != 0
        {
            print(response.invalidProductIdentifiers.description)
        }

        NSNotificationCenter.defaultCenter().postNotificationName(productsLoadedNotification, object: nil)
    }

}

// MARK: - Transaction delegate methods

extension PurchaseManager: SKPaymentTransactionObserver
{
    func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction])
    {
        for transaction in transactions
        {
            switch transaction.transactionState
            {
            case .Purchasing:
                print("Transaction in Progress")
            case .Purchased:
                print("Transaction completed successfully.")
                SKPaymentQueue.defaultQueue().finishTransaction(transaction)

                // SUCCESS GIVE LIMITS

                self.transactionProgress = false
                // Give limits
                BuyLimitsViewController.sharedInstance.giveLimits(self.purchaseItemID)
                self.setPurchasedProduct(self.purchaseItemID)

                self.delegate?.refreshList()


                // Send Values 
                let addIAPUrl = "http://bla.com/)&price=\(getprice)"
                self.sendIAP(addIAPUrl, completionHandler: { (success, message) -> Void in


                        if(success == 1){

                            dispatch_async(dispatch_get_main_queue()){

                                // ADDED

                            }

                        }else{

                            // DONT ADDED
                        }

                    })

            case .Failed:
                print("Transaction Failed");
                SKPaymentQueue.defaultQueue().finishTransaction(transaction)
                transactionProgress = false
                self.delegate?.refreshList()
            case .Restored:
                print("Restore completed successfully.")
                let identifier = transaction.originalTransaction!.payment.productIdentifier
                SKPaymentQueue.defaultQueue().finishTransaction(transaction)
                transactionProgress = false
                self.setPurchasedProduct(identifier)
            case .Deferred:
                print("Transaction defered.")
                print(transaction.transactionState.rawValue)
                transactionProgress = false
                self.delegate?.refreshList()
            }
        }
    }



    func sendIAP(url : String, completionHandler : ((success : Int, message : String) -> Void)) {

        guard let url = NSURL(string: url as String) else {
            completionHandler(success: 0, message: "Couldn't get URL")
            return
        }

        let urlRequest = NSURLRequest(URL: url)
        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        let session = NSURLSession(configuration: config)

        let task = session.dataTaskWithRequest(urlRequest, completionHandler: { (data,  response, error) in
            guard let responseData = data else {
                completionHandler(success: 0, message: "Data was nil")
                return
            }
            guard error == nil else {
                print(error)
                completionHandler(success: 0, message: "Error wasn't nil")
                return
            }

            let post: NSDictionary
            do {
                post = try NSJSONSerialization.JSONObjectWithData(responseData,
                    options: []) as! NSDictionary
            } catch  {
                completionHandler(success: 0, message: "Error with NSJSONSerialization")
                return
            }

            let numberFromString = Int((post["success"] as? String)!)


            completionHandler(success: (numberFromString)!, message: (post["message"] as? String)!)



        })
        task.resume()


    }


    func setPurchasedProduct(productID: NSString)
    {
        NSUserDefaults.standardUserDefaults().setBool(true, forKey: productID as String)
        NSUserDefaults.standardUserDefaults().synchronize()
    }

    func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) {
        print("Restore Completed")
        self.delegate?.restoreCompleted()
    }


}

这里是我的buyView控制器

import UIKit
import StoreKit

class BuyLimitsViewController: UIViewController, UITextFieldDelegate, PurchaseManagerDelegate, UITableViewDataSource, UITableViewDelegate{

    static let sharedInstance = BuyLimitsViewController()

    @IBOutlet weak var tableView: UITableView!

    var items = []

    var purchaseManager = PurchaseManager()

    override func viewDidLoad() {
        super.viewDidLoad()

        purchaseManager.delegate = self
        purchaseManager.loadPaymentInfo()

        if let path = NSBundle.mainBundle().pathForResource("PurchaseID", ofType: "plist")
        {
            if let fileItems = NSArray(contentsOfFile: path)
            {
                items = fileItems
            }
        }

        let mainQueue = NSOperationQueue.mainQueue()

        NSNotificationCenter.defaultCenter().addObserverForName(purchaseManager.productsLoadedNotification, object: nil, queue: mainQueue) { _ in
            self.tableView.reloadData()
        }

    }

    // MARK: - TableView delegate

    func numberOfSectionsInTableView(tableView: UITableView) -> Int
    {
        return items.count
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        var numberOfItems = 0
        if let purchaseItems = items[section] as? [String]
        {
            numberOfItems = purchaseItems.count
        }

        return numberOfItems
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCellWithIdentifier("StoreTableViewCell") as! StoreTableViewCell

        if let purchaseItems = items[indexPath.section] as? [String]
        {
            let productID = purchaseItems[indexPath.row]
            if purchaseManager.productsAreLoaded()
            {
                cell.accessoryView = nil
                cell.titleLabel.text = purchaseManager.getProductTitle(productID)
                cell.priceLabel.text = purchaseManager.getProductPrice(purchaseItems[indexPath.row])

            }
            else
            {
                cell.titleLabel.text = ""
                cell.priceLabel.text = ""
                if (indexPath.section == 0) && (indexPath.row == 0)
                {
                    cell.titleLabel.text = "Loading..."
                    cell.accessoryView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
                    (cell.accessoryView as! UIActivityIndicatorView).startAnimating()
                }
            }
        }

        return cell
    }


    func giveLimits(purhased : NSString) {


        let postEndpointLost:NSString = "http://bla.com/"
        user.sharedInstance.apiRequest(postEndpointLost as String, completionHandler: { (success, message) -> Void in

            if(success == 1){

                dispatch_async(dispatch_get_main_queue()){


                }

            }else{

                dispatch_async(dispatch_get_main_queue()){


                }

            }

        })

    }


    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
    {
        if let purchaseItems = items[indexPath.section] as? [String]
        {
            let productID = purchaseItems[indexPath.row]
            if !purchaseManager.isProductBought(productID)
            {
                purchaseManager.buyProduct(purchaseItems[indexPath.row])
            }
        }
    }

    @IBAction func restoreButtonSelector(sender: AnyObject) {
        purchaseManager.restorePurchases()
    }

    // MARK: - Purchase Manager delegate

    func refreshList()
    {
        self.tableView.reloadData()
    }

    func transactionIsActive()
    {
        let alert = UIAlertController(title: "", message: "Transaction is already in progress. Please wait to finish.", preferredStyle: UIAlertControllerStyle.Alert)

        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: { alertAction in
            self.tableView.reloadData()
            alert.dismissViewControllerAnimated(true, completion: nil)
        }))

        self.presentViewController(alert, animated: true, completion: nil)
    }

    func restoreCompleted()
    {
        let alert = UIAlertController(title: "", message: "Restore completed.", preferredStyle: UIAlertControllerStyle.Alert)

        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: { alertAction in
            self.tableView.reloadData()
            alert.dismissViewControllerAnimated(true, completion: nil)
        }))

        self.presentViewController(alert, animated: true, completion: nil)
    }



}

每个load buyviewcontroller的输出示例+1计数此输出示例

Transaction in Progress
Transaction in Progress
Transaction in Progress
Transaction in Progress

我认为当用户点击购买限制视图控制器时我可能需要明确一些事情我需要你的帮助谢谢!

1 个答案:

答案 0 :(得分:1)

你没有removeTransactionObserver。因此,每次在viewDidLoad()中,它都会在默认的paymentQueue

上添加事务观察器
SKPaymentQueue.defaultQueue().addTransactionObserver(self)

要解决此问题,请在removeTransactionObserver中执行viewWillDisappear。在StoreViewController中写道:

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)

    purchaseManager.removeTransactionObserver()
}

PurchaseManager中添加一项功能:

func removeTransactionObserver()
{
    SKPaymentQueue.defaultQueue().removeTransactionObserver(self)
}