<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[In App Purchase Tutorial on Exported Projects]]></title><description><![CDATA[<p dir="auto">In App purchase swift code for exported projects:</p>
<p dir="auto">first add pod 'SwiftyStoreKit' to the list of pods in Podfile in a text editor.</p>
<p dir="auto">Then in terminal, run pod install. If you don't have cocoapods installed on your mac, follow the instructions here: <a href="https://guides.cocoapods.org/using/getting-started.html" target="_blank" rel="noopener noreferrer nofollow ugc">https://guides.cocoapods.org/using/getting-started.html</a></p>
<p dir="auto">Replace the contents of HPSwift.swift with the following file</p>
<pre><code>//
//  HPSwift.swift
//  hyperPad-Project
//
//  Created by Hamed Saadat on 2019-08-07.
//

import Foundation
import SwiftyStoreKit

@objc class HPSwift: NSObject {
    fileprivate var _behaviours: HPBehaviours? = nil
    @objc var behaviours: HPBehaviours? {
        get {
            return _behaviours
        }
        
        set(behaviours) {
            _behaviours = behaviours
            
            SwiftyStoreKit.completeTransactions(atomically: true) { purchases in
                for purchase in purchases {
                    switch purchase.transaction.transactionState {
                    case .purchased, .restored:
                        if purchase.needsFinishTransaction {
                            // Deliver content from server, then:
                            SwiftyStoreKit.finishTransaction(purchase.transaction)
                        }
                        // Unlock content
                        behaviours?.broadcastValue(purchase.productId as NSString, withKey: "purchaseComplete")
                        
                    case .failed, .purchasing, .deferred:
                        behaviours?.broadcastValue(purchase.productId as NSString, withKey: "purchaseError")
                        break // do nothing
                    @unknown default:
                        break
                    }
                }
            }
            
            behaviours?.addReceiveKey("restorePurchases", onReceive: { (receiveValue) in
                SwiftyStoreKit.restorePurchases(atomically: true) { results in
                    if results.restoreFailedPurchases.count &gt; 0 {
                        behaviours?.broadcastValue("Restore Failed: \(results.restoreFailedPurchases)" as NSString, withKey: "purchaseError")
                    }
                    else if results.restoredPurchases.count &gt; 0 {
                        results.restoredPurchases.forEach { (purchase) in
                            behaviours?.broadcastValue(purchase.productId as NSString, withKey: "purchaseComplete")
                        }
                    }
                    else {
                        print("Nothing to Restore")
                    }
                }
            })
            
            /*
             Add Behaviour functionality here
            */
            
            behaviours?.addReceiveKey("purchase", onReceive: { (recieveValue) in
                 // handle in app purchase logic! //
                    SwiftyStoreKit.purchaseProduct("INSERT_PURCHASE_IDENTIFIER_HERE_OR_USE_recieveValue", quantity: 1, atomically: true) { result in
                        switch result {
                        case .success(let purchase):
                            behaviours?.broadcastValue(purchase.productId as NSString, withKey: "purchaseComplete")
                        case .error(let error):
                            var message = ""
                            switch error.code {
                            case .unknown: message = "Unknown error. Please contact support"
                            case .clientInvalid: message = "Not allowed to make the payment"
                            case .paymentCancelled: break
                            case .paymentInvalid: message = "The purchase identifier was invalid"
                            case .paymentNotAllowed: message = "The device is not allowed to make the payment"
                            case .storeProductNotAvailable: message = "The product is not available in the current storefront"
                            case .cloudServicePermissionDenied: message = "Access to cloud service information is not allowed"
                            case .cloudServiceNetworkConnectionFailed: message = "Could not connect to the network"
                            case .cloudServiceRevoked: message = "User has revoked permission to use this cloud service"
                            default: message = ((error as NSError).localizedDescription)
                            }
                            behaviours?.broadcastValue(message as NSString, withKey: "purchaseFailed")
                        }
                    }
            })
        }
    }
    
}
</code></pre>
<p dir="auto">Some key points:</p>
<pre><code>behaviours?.addReceiveKey("restorePurchases", onReceive: { (receiveValue) in
                // add your code here
            })
</code></pre>
<p dir="auto">Will get triggered when you trigger a broadcast behaviour with the restorePurchases key</p>
<p dir="auto"><code>behaviours?.broadcastValue(purchase.productId as NSString, withKey: "purchaseComplete")</code></p>
<p dir="auto">Will trigger a receive message behaviour with the <code>purchaseComplete</code> key</p>
<p dir="auto"><code>INSERT_PURCHASE_IDENTIFIER_HERE_OR_USE_recieveValue</code> can be replaced with either the identifier of your purchase from AppStoreConnect. OR the <code>receiveValue</code> parameter. If you use receiveValue make sure in your broadcast behaviour, you're sending the identifier from App Store Connect.</p>
]]></description><link>https://forum.hyperpad.com/topic/1802/in-app-purchase-tutorial-on-exported-projects</link><generator>RSS for Node</generator><lastBuildDate>Wed, 07 Oct 2026 02:58:00 GMT</lastBuildDate><atom:link href="https://forum.hyperpad.com/topic/1802.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 27 Nov 2023 20:33:34 GMT</pubDate><ttl>60</ttl></channel></rss>