2016-03-01 80 views
1

你好,我有工作的应用程序,当用户点击购买限制视图控制器(第一次点击)用户买了一切都好,但当用户回到主控制器,并再次购买限制视图控制器和用户点击购买IAP做双重交易和用户也再次去主控制器,并再次购买限制视图控制器时,点击购买IAP做三重交易..我如何解决这个问题我的代码在下面。Swift IAP multiple交易时返回并再次查看控制器

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) 
    } 



} 

为每个负载buyviewcontroller +1计数这个输出例如

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

我想也许输出的例子就需要明确出头的时候userclick购买限制视图控制器我需要你的帮助谢谢!

+0

什么想法?我该如何解决它?我认为在购买限制视图控制器重写func viewDidLoad(){}里面错了吗?当用户再次购买限制视图控制器重复某些事情? – SwiftDeveloper

回答

1

您没有做过removeTransactionObserver。因此,在viewDidLoad()每次它在默认paymentQueue

SKPaymentQueue.defaultQueue().addTransactionObserver(self) 

为了应对,加入交易的观察者,在viewWillDisappearremoveTransactionObserver。在StoreViewController写:

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

    purchaseManager.removeTransactionObserver() 
} 

添加功能PurchaseManager

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

谢谢你!我认为会使用很多人 – SwiftDeveloper