Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in-app purchase in Swift with a single product

Is there a simple way to implement a in-app purchase in swift for a single product?

I want a button that triggers the in-app purchase like a [ad-removal] or [unlock-premium-content]

I can't understand the full logic of it.

I'm trying to follow and translate this tutorial from [Techotopia] http://www.techotopia.com/index.php/An_iOS_7_In-App_Purchase_Tutorial

But It's my first time with the StoreKit Framework, and also with Swift.

I just want to know the logic of the in-app purchase transaction with the Swift StoreKit Framework.

Thanks!

like image 955
angeant Avatar asked Oct 07 '14 12:10

angeant


People also ask

What is considered an in-app purchase?

In-app purchases allow developers to offer the app for free in the App Store (for iOS) and Google Play (for Android). Then, within the application, they can upsell and advertise paid upgrades, locked features, special items, and other premium offers.

Is in-app purchase mandatory in iOS?

Also, Apple Pay can be used for purchasing services such as club memberships, hotel reservations, and tickets for events. You are required to use Apple's In-App Purchase to sell virtual goods such as premium content for your app and subscriptions for digital content.


1 Answers

Step 0: In your iTunes Connect account, create an In-App purchase.

For Single purchases, use this method:

  1. Import
import StoreKit 
  1. Conform to StoreKit Delegate
class YOURViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver { 
  1. Use a user default to track transactions
let defaults = NSUserDefaults.standardUserDefaults() 
  1. Product ID. This one will be same as in your iTunes Connect in app purchase
var product_id: NSString?  override func viewDidLoad() {             product_id = "YOUR_PRODUCT_ID"     super.viewDidLoad()     SKPaymentQueue.defaultQueue().addTransactionObserver(self)      //Check if product is purchased      if (defaults.boolForKey("purchased")){          // Hide a view or show content depends on your requirement        overlayView.hidden = true          } else if (!defaults.boolForKey("stonerPurchased")) {         print("false")                 } } 
  1. Unlock Content. This is button action which will initialize purchase
@IBAction func unlockAction(sender: AnyObject) {     print("About to fetch the products")     // We check that we are allow to make the purchase.    if (SKPaymentQueue.canMakePayments()) {         var productID:NSSet = NSSet(object: self.product_id!);         var productsRequest:SKProductsRequest = SKProductsRequest(productIdentifiers: productID);         productsRequest.delegate = self;         productsRequest.start();         println("Fetching Products");     } else {         print("can't make purchases");     }     } 
  1. Helper Methods
func buyProduct(product: SKProduct) {     println("Sending the Payment Request to Apple");     var payment = SKPayment(product: product)     SKPaymentQueue.defaultQueue().addPayment(payment); } 
  1. Delegate Methods for IAP
func productsRequest (request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {      var count : Int = response.products.count     if (count>0) {         var validProducts = response.products         var 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: [AnyObject]!)    {     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")                 overlayView.hidden = true                 break;             case .Failed:                 print("Purchased Failed");                 SKPaymentQueue.defaultQueue().finishTransaction(transaction as SKPaymentTransaction)                 break;             case .Restored:                 print("Already Purchased");                 SKPaymentQueue.defaultQueue().restoreCompletedTransactions()                 default:                 break;             }         }     }         } 

Swift > 3.0

import StoreKit class YOURVIEWController:UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver {  let product_id: NSString = "com.some.inappid" // <!-- Change it to your inapp id 

In your viewDidLoad add

override func viewDidLoad() {     super.viewDidLoad()     SKPaymentQueue.default().add(self) 

In your buy button action

@IBAction func buyNowAction(_ sender: UIButton) {       if (SKPaymentQueue.canMakePayments()) {         let productID:NSSet = NSSet(array: [self.product_id as NSString]);         let productsRequest:SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>);         productsRequest.delegate = self;         productsRequest.start();         print("Fetching Products");     } else {         print("can't make purchases");     } } 

In Your Restore button action

// MARK: - Restore In App Purchase     @IBAction func restoreAction(_ sender: UIButton) {      if (SKPaymentQueue.canMakePayments()) {         SKPaymentQueue.default().add(self)         SKPaymentQueue.default().restoreCompletedTransactions()     } else {         // show error     }  } 

Add Delegates:

// SKProductRequest Delegate  func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {      print(response.products)     let count : Int = response.products.count     if (count>0) {          let validProduct: SKProduct = response.products[0] as SKProduct         if (validProduct.productIdentifier == self.product_id as String) {             print(validProduct.localizedTitle)             print(validProduct.localizedDescription)             print(validProduct.price)             self.buyProduct(product: validProduct)         } else {             print(validProduct.productIdentifier)         }     } else {         print("nothing")     } }  func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {     for transaction:AnyObject in transactions {         if let trans:SKPaymentTransaction = transaction as? SKPaymentTransaction{              self.dismissPurchaseBtn.isEnabled = true             self.restorePurchaseBtn.isEnabled = true             self.buyNowBtn.isEnabled = true              switch trans.transactionState {             case .purchased:                 print("Product Purchased")                 //Do unlocking etc stuff here in case of new purchase                 SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)                  break;             case .failed:                 print("Purchased Failed");                 SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)                 break;             case .restored:                 print("Already Purchased")                 //Do unlocking etc stuff here in case of restor                  SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)             default:                 break;             }         }     } }   //If an error occurs, the code will go to this function     func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {         // Show some alert     } 
like image 102
Saqib Omer Avatar answered Sep 22 '22 16:09

Saqib Omer