Skip to content

maximbilan/iOS-Swift-In-App-Purchases-Sample

Repository files navigation

iOS Swift In-App-Purchases

I would like to tell how to create a simple application with in-app-purchases using Swift.

First of all you need to create product IDs in iTunes Connect for your application.

alt tag alt tag

Lets create a class InAppPurchase. Inherited from the following protocols:

class InAppPurchase : NSObject, SKProductsRequestDelegate, SKPaymentTransactionObserver

InAppPurchase class will be singleton, for easy management of purchases.

class var sharedInstance : InAppPurchase {
    struct Static {
        static var onceToken: dispatch_once_t = 0
        static var instance: InAppPurchase? = nil
    }
    dispatch_once(&Static.onceToken) {
        Static.instance = InAppPurchase()
    }
    return Static.instance!
}

Add some constants for notifications:

let kInAppProductPurchasedNotification = "InAppProductPurchasedNotification"
let kInAppPurchaseFailedNotification   = "InAppPurchaseFailedNotification"
let kInAppProductRestoredNotification  = "InAppProductRestoredNotification"
let kInAppPurchasingErrorNotification  = "InAppPurchasingErrorNotification"

And for product IDs:

let unlockTestInAppPurchase1ProductId = "com.testing.iap1"
let unlockTestInAppPurchase2ProductId = "com.testing.iap2"

In the initialization of class, we need to add a observer:

SKPaymentQueue.defaultQueue().addTransactionObserver(self)

For starting of making purchase, we need to run a product request:

if SKPaymentQueue.canMakePayments() {
    let productID: NSSet = NSSet(object: productIdentifier)
    let productsRequest: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set)
    productsRequest.delegate = self
    productsRequest.start()
}
else {
    print(“Сan’t make purchases”)
}

After that if is it a success, will be called:

func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
    var count: Int = response.products.count
    if count > 0 {
        let validProduct: SKProduct = response.products[0] as! SKProduct
        buyProduct(validProduct)
    }
    else {
        print(“No products”)
    }
}

If error:

func request(request: SKRequest!, didFailWithError error: NSError!) {
    print("Error %@ \(error)")
}

In the buyProduct method we need to add a payment to payment queue:

let payment = SKPayment(product: product)
SKPaymentQueue.defaultQueue().addPayment(payment)

And after that will be called paymentQueue callback:

func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {
    for transaction: AnyObject in transactions {
        if let trans: SKPaymentTransaction = transaction as? SKPaymentTransaction {
            switch trans.transactionState {
                case .Purchased:
                    SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
                break
 
                case .Failed:
                    SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
                break

                case .Restored:
                    SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
                break
           
                default:
                break
        }
    }
}

If you did everything right, you should see the similar:

alt tag alt tag alt tag

For testing the app, please use sandbox accounts, which you can create in iTunes Connect.

For updating UI in your application in the example I use notifications, and for checking if already unlocked purchases or not, I use NSUserDefaults.

Please see the full sample in this repository, feel free to use and don’t forget to like the repository :) Thanks for attention.