This page contains samples of code integration in Swift for iOS.

NOTE 1: On iOS, the version that is checked during validation is the one stored in the CFBundleVersion field of the Info.plist file. Never put the version in the CFBundleShortVersionString field.

NOTE 2: These examples only covers a small subset of the possible behaviors. Carefully check the signature of the receipt validation function to learn about the required arguments.

NOTE 3: These examples serve as a basis to show you how to integrate the code and call it. Remember that you have to be creative in the way you integration validation code.

Basic receipt validation

This kind of validation should be executed in the early stage of the application's lifetime. When the validation succeeds, nothing happens; if the validation fails a receipt refresh request will be created and started.

Use the following options for the code generation (replace with your own values):

You need to implement the SKRequestDelegate protocol in order to receive notifications of the receipt refresh request. Then, call the validation code by passing the request delegate instance. Note that the requestDidFinish: method is called even when the user has cancelled the request; you may have to trigger another receipt validation in this method or later to be sure that the user has confirmed his credentials.

//
// MyClass.swift
//
import Foundation
import StoreKit

public class MyClass: SKRequestDelegate {

    // ...

    func strategicPlace() {
        <Your Code Prefix>_CheckReceipt(request_delegate: self)
    }

    // ...

    func request(_ request: SKRequest, didFailWithError error: Error) {
        // There was an error during refresh request
    }

    func requestDidFinish(_ request: SKRequest) {
        // The refresh request has finished
        let url = Bundle.main.appStoreReceiptURL
        if FileManager.default.fileExists(atPath: url!.path) {
            // Receipt has been retrieved
        } else {
            // Trigger a new validation
            DispatchQueue.main.async {
                <Your Code Prefix>_CheckReceipt(request_delegate: self)
            }
        }
    }

    // ...

}

Retrieving receipt properties

This kind of validation is useful when you want to access to some receipt properties like the original bundle version (i.e. the version that was originally purchased). Whether the validation succeeds or fails, the given block will be called.

Use the following options for the code generation (replace with your own values):

In a strategic place (in a class for example), call the validation function.

//
// MyClass.swift
//
import Foundation

public class MyClass {

    // ...

    func strategicPlace() {
        <Your Code Prefix>_CheckReceipt(callback_block: { (receiptDictionary, validationResult) in
            print(validationResult)
            if validationResult, let dictionary = receiptDictionary {
                print("-> \(dictionary[<Your Code Prefix>_RECEIPT_BUNDLE_ID] ?? "-")")
                print("-> \(dictionary[<Your Code Prefix>_RECEIPT_BUNDLE_VERSION] ?? "-")")
                print("-> \(dictionary[<Your Code Prefix>_RECEIPT_ORIGINAL_APPLICATION_VERSION] ?? "-")")
            }
        })
    }

    // ...

}

Checking InApp purchases

This kind of validation is used when you need to access the InApp purchase stored in the receipt. When the validation succeeds, the InApp purchases will be checked; if the validation fails nothing will be done.

Use the following options for the code generation (replace with your own values):

The code validates the receipt and call-back the given block for each given product identifiers. If the product identifier is found in the receipt, the block will be called back with the purchase information. Otherwise, no information will be provided.

//
// MyClass.swift
//
import Foundation

public class MyClass {

    // ...

    func strategicPlace() {
        // An array of the product identifiers to query in the receipt
        let identifiers = ["RECEIGEN_CONSUMABLE", "RECEIGEN_NON_CONSUMABLE", "OTHER"]
        <Your Code Prefix>_CheckReceipt(inapp_identifiers: identifiers, { (identifier, isPresent, purchaseInfo) in 
            if isPresent,
               let info = purchaseInfo,
               let quantity = info[<Your Code Prefix>INAPP_QUANTITY] {
               print(">>> \(identifier) x \(quantity)")
            } else {
               print(">>> \(identifier) not found")
            }
        })
    }

    // ...

}

Checking InApp purchases and access receipt properties

This kind of validation is used when you need to access the InApp purchase stored in the receipt, while also accessing to the receipt properties. When the validation succeeds, the InApp purchases will be checked; if the validation fails nothing will be done.

Use the following options for the code generation (replace with your own values):

The code validates the receipt and call-back the given block for each given product identifiers. If the product identifier is found in the receipt, the block will be called back with the purchase information. Otherwise, no information will be provided.

//
// MyClass.swift
//
import Foundation

public class MyClass {

    // ...

    func strategicPlace() {
        // An array of the product identifiers to query in the receipt
        let identifiers = ["RECEIGEN_CONSUMABLE", "RECEIGEN_NON_CONSUMABLE", "OTHER"]
        <Your Code Prefix>_CheckInAppPurchasesAndReceipt(inapp_identifiers: identifiers, { (receiptDictionary, identifier, isPresent, purchaseInfo) in 
            if let dictionary = receiptDictionary {
                print("-> \(dictionary[<Your Code Prefix>_RECEIPT_ORIGINAL_APPLICATION_VERSION] ?? "-")")
            }
            if isPresent,
               let info = purchaseInfo,
               let quantity = info[<Your Code Prefix>INAPP_QUANTITY] {
               print(">>> \(identifier) x \(quantity)")
            } else {
               print(">>> \(identifier) not found")
            }
        })
    }

    // ...

}