2016-02-10 8 views
1

Этот вопрос заставил меня работать в течение нескольких дней.Кнопка покупки и восстановления в приложении: отдельный продукт - нерасходуемый

У меня есть простое приложение, которое отображает баннеры и межстраничные объявления.

Я использую одно приложение просмотра, есть главный контроллер представления (ViewController.swift) и создал другой контроллер представления (InAppViewController.swift) для обработки всплывающей страницы, которая:

  1. Позволяет пользователь сделать в приложении для удаления всех объявлений (AdBanners & InterstitialAds); или
  2. Восстановить покупки.

Мой код является безошибочным, когда я его запускаю.

Покупки в приложении работают нормально, но иногда я получаю запрос на вход в iTunes дважды.

Но проблема с моей кнопкой восстановления и связанной с ней функциональностью.

У меня есть множество учетных записей тестовых программ для песочницы, и новый пользователь, который не купил приложение, может успешно восстановить покупки. Что не должно быть возможным, поэтому я определенно сделал что-то не так.

Вот мой код:

Главная View Controller:

// ViewController.swift 

import UIKit 
import MessageUI 
import Social 
import iAd 
import StoreKit 

class ViewController: UIViewController, MFMailComposeViewControllerDelegate, MFMessageComposeViewControllerDelegate, ADBannerViewDelegate, ADInterstitialAdDelegate 
{ 

let defaults = NSUserDefaults.standardUserDefaults() 
var product_id: NSString?; 

override func viewDidLoad() { 
    product_id = "some.product.id"; 
    super.viewDidLoad() 

    //Check if product is purchased 
    if (defaults.boolForKey("purchased")){ 
     print("already purchased") 

     // Hide or show banner ads is purchased/not purchased. 
     // Advertising Banner: 
     self.canDisplayBannerAds = false 
     } 

    else if (!defaults.boolForKey("stonerPurchased")){ 
     print("not yet purchased") 

     // Advertising Banner: 
     self.canDisplayBannerAds = true 
     } 

Этот код, кажется, работает отлично. Когда приложение загружается, оно может определить, кто заплатил за удаление объявлений и тех, кто не заплатил, а рекламные баннеры показаны соответствующим образом.

Он находится во втором контроллере (InAppPViewController.swift). У меня возникают проблемы.

вот мой код:

Second View Controller - InAppViewController.swift:

// InAppPViewController.swift 

import UIKit 
import StoreKit 
import iAd 

class InAppPViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver { 

let defaults = NSUserDefaults.standardUserDefaults() 
var product_id: NSString?; 


@IBOutlet weak var unlockAction: UIButton! 
@IBOutlet var adBannerView: ADBannerView? 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Do any additional setup after loading the view. 
    } 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

    @IBAction func restorePurchases(sender: UIButton) { 
    SKPaymentQueue.defaultQueue().addTransactionObserver(self) 
    SKPaymentQueue.defaultQueue().restoreCompletedTransactions() 

} 
    func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) { 

    print("Transactions Restored") 
    let alert = UIAlertView(title: "Thank You", message: "Your purchase(s) were restored.", delegate: nil, cancelButtonTitle: "OK") 
    alert.show() 
} 


@IBAction func unlockAction(sender: AnyObject) { 

product_id = "some.product.id"; 

    SKPaymentQueue.defaultQueue().addTransactionObserver(self) 

    //Check if product is purchased 

    if (defaults.boolForKey("purchased")){ 

    } 
    else if (!defaults.boolForKey("stonerPurchased")){ 
     print("false")  
    } 


    print("About to fetch the products"); 
    // We check that we are allowed to make the purchase. 

    if (SKPaymentQueue.canMakePayments()) 
    { 
     let productID:NSSet = NSSet(object: self.product_id!); 
     let productsRequest:SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>); 
     productsRequest.delegate = self; 
     productsRequest.start(); 
     print("Fething Products"); 
    }else{ 
     print("can't make purchases"); 
    } 

} 

func buyProduct(product: SKProduct){ 
    print("Sending the Payment Request to Apple"); 
    let payment = SKPayment(product: product) 
    SKPaymentQueue.defaultQueue().addPayment(payment); 

} 
//Delegate Methods for IAP 

func productsRequest (request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) { 

    let count : Int = response.products.count 
    if (count>0) { 

     let validProduct: SKProduct = response.products[0] as SKProduct 
     if (validProduct.productIdentifier == self.product_id) { 
      print(validProduct.localizedTitle) 
      print(validProduct.localizedDescription) 
      print(validProduct.price) 
      buyProduct(validProduct); 
     } else { 
      print(validProduct.productIdentifier) 
     } 
    } else { 
     print("nothing") 
    } 
} 


func request(request: SKRequest, didFailWithError error: NSError) { 
    print("Error Fetching product information"); 
} 

func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { 
    print("Received Payment Transaction Response from Apple"); 

    for transaction:AnyObject in transactions { 
     if let trans:SKPaymentTransaction = transaction as? SKPaymentTransaction{ 
      switch trans.transactionState { 

      case .Purchased: 
       print("Product Purchased"); 
       SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction) 
       defaults.setBool(true , forKey: "purchased") 
       break; 

      case .Failed: 
       print("Purchased Failed"); 
       SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction) 
       break; 

      case .Restored: 
       print("Already Purchased"); 
       SKPaymentQueue.defaultQueue().restoreCompletedTransactions() 


      default: 
       break; 
      } 
     } 
    } 

} 

}

Где я буду неправильно?

Вопросы:

  1. ли мой выше код правильно?
  2. Что мне изменить и почему?

Извинения заранее, я новичок в этом замечательном мире кодирования ... но любящим каждую минуту этого!

+0

Не редактируйте свой ответ в своем вопросе. Отправьте его как ответ. –

+0

@ Daniel Storm Но если я не уверен, что мой ответ верен, и я отправляю то, что, на мой взгляд, является ответом, тогда я фактически закрою свой вопрос, как ответил? И я не получу то, что может быть лучшим ответом? –

+2

Вы можете опубликовать свой ответ и * не принимать его *, таким образом, другие пользователи могут отправлять ответы. Ну, они могли бы также опубликовать, если вы примете свой ответ, но он действительно может отправить сообщение, что вы нашли решение. Итак, да: вы можете удалить это из вопроса и опубликовать его в качестве ответа. Если кто-то отправляет сообщение лучше, вы всегда можете удалить свой. – Moritz

ответ

0

Я изменен мой код для файла InAppPViewController.swift следующим образом:

// InAppPViewController.swift 

import UIKit 
import StoreKit 

class InAppPViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver { 

let defaults = NSUserDefaults.standardUserDefaults() 
var product_id: NSString?; 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Do any additional setup after loading the view. 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

@IBAction func restorePurchases(sender: UIButton) { 
    // Set up the observer 
    SKPaymentQueue.defaultQueue().addTransactionObserver(self) 


    //Check if user can make payments and then proceed to restore purchase 
    if (SKPaymentQueue.canMakePayments()) { 
     SKPaymentQueue.defaultQueue().restoreCompletedTransactions() 
    } 

} 

@IBAction func unlockAction(sender: AnyObject) { 

    product_id = "some.product.id"; 
    // Adding the observer 
    SKPaymentQueue.defaultQueue().addTransactionObserver(self) 

    //Check if product is purchased 
    if (defaults.boolForKey("purchased")){ 
     print("User already purchased this") 
     // Hide a view or show content depends on your requirement 
    } 

    else if (!defaults.boolForKey("Purchased")){ 
     print("User has not yet pur hased this") 
    } 


    print("About to fetch the products"); 

    // Check if user can make payments and then proceed to make the purchase. 
    if (SKPaymentQueue.canMakePayments()) 
    { 
     let productID:NSSet = NSSet(object: self.product_id!); 
     let productsRequest:SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>); 
     productsRequest.delegate = self; 
     productsRequest.start(); 
     print("User can make purchases and will fetch products from Apple Store now"); 
    }else{ 
     print("User can't make purchases"); 
    } 

} 

func buyProduct(product: SKProduct){ 
    print("Sending the Payment Request to Apple"); 
    let payment = SKPayment(product: product) 
    SKPaymentQueue.defaultQueue().addPayment(payment); 

} 

func productsRequest (request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) { 

    let count : Int = response.products.count 
    if (count>0) { 

     let validProduct: SKProduct = response.products[0] as SKProduct 
     if (validProduct.productIdentifier == self.product_id) { 
      print(validProduct.localizedTitle) 
      print(validProduct.localizedDescription) 
      print(validProduct.price) 
      buyProduct(validProduct); 
     } else { 
      print(validProduct.productIdentifier) 
     } 
    } else { 
     print("nothing") 
    } 
} 


func request(request: SKRequest, didFailWithError error: NSError) { 
    print("Error Fetching product information"); 
} 

// Allowing for all possible outcomes: 
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { 
    print("Received Payment Transaction Response from Apple"); 

    for transaction:AnyObject in transactions { 
     if let trans:SKPaymentTransaction = transaction as? SKPaymentTransaction { 
      switch trans.transactionState { 

      case .Purchased: 
       print("Product Purchased") 
       let alert = UIAlertView(title: "Thank You", message: "Thank you for your purchase!", delegate: nil, cancelButtonTitle: "OK") 
       alert.show(); 
       SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction) 
       defaults.setBool(true , forKey: "purchased") 
       break; 

      case .Failed: 
       print("Purchased Failed"); 
       SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction) 
       break; 

      case .Restored: 
       print("Already Purchased"); 
       SKPaymentQueue.defaultQueue().restoreCompletedTransactions() 
       break; 

      default: 
       break; 
      } 
     } 
    } 

} 

}

я оставил файл ViewController.swift как есть.

Приобретение товаров, похоже, сейчас работает.

Но в отношении восстановления покупок я могу запустить код на своем физическом устройстве, но не может проверить функцию «Восстановить покупки».

Я пойман с previous Восстановить покупки, которые до сих пор не решены и не зацикливаются в системе. Я не могу очистить свой SKPaymentsQueue вручную. Таким образом, мой код отказывается больше развлекать новые запросы на восстановление.

1
  1. SKPaymentQueue.defaultQueue().addTransactionObserver(self) должен быть в viewDidLoad() не восстановить Func
  2. Вы можете поставить SKPaymentQueue.defaultQueue().restoreCompletedTransactions() как этот override func viewWillDisappear(animated: Bool) { SKPaymentQueue.defaultQueue().removeTransactionObserver(self) }
  3. логин дважды в песочнице нормально.

Надеюсь, я помог чему-то.