This page contains samples of code integration in Swift for OS X.

NOTE 1: On OS X, the version that is checked during validation is the one stored in the CFBundleShortVersionString field of the Info.plist file. Never put the version in the CFBundleVersion 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.

Startup receipt validation

This validation is required as per Apple rules so receipt validation occurs immediately after the application is launched. When the validation succeeds the application is run; when the validation fails the application will exit with a code 173.

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

Create a main.swift file that serves as an entry point. Note that validation function is public and global. Be sure to remove any remaining @NSApplicationMain to avoid conflict.

//
// main.swift
//
import Cocoa

<Your Code Prefix>_CheckReceiptAndRun(argc: CommandLine.argc, CommandLine.unsafeArgv)

Receipt validation during application’s lifecycle

This kind of validation should be executed during the application’s lifetime to ensure that the initial check has not been by-passed. When the validation succeeds nothing happens; when the validation fails the application will exit with a code 173.

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. Note that validation function is public and global.

//
// MyClass.swift
//
import Foundation

public class MyClass {

    // ...

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

    // ...

}

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 the application will exit with a code 173.

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 the application will exit with a code 173.

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

    // ...

}