in app purchase in SKScene
First, put this in your game scene line and make sure you have the framework 'StoreKit' imported
class GameScene: SKScene, SKPaymentTransactionObserver, SKProductsRequestDelegate {
Next, your going to want to put these lines in your didmovetoview. Keep in mind that after the "objects:" The string you put should be the in app purchase identifier you set up using iTunes connect.
// Set IAPS
if(SKPaymentQueue.canMakePayments()) {
println("IAP is enabled, loading")
var productID:NSSet = NSSet(objects: "Put IAP id here")
var request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as Set<NSObject>)
request.delegate = self
request.start()
} else {
println("please enable IAPS")
}
Outside of any other functions, but still within the game scene, insert these functions and variables
//In App Purchases
var list = [SKProduct]()
var p = SKProduct()
func buyProduct() {
println("buy " + p.productIdentifier)
var pay = SKPayment(product: p)
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment)
}
func productsRequest(request: SKProductsRequest!, didReceiveResponse response: SKProductsResponse!) {
println("product request")
var myProduct = response.products
for product in myProduct {
println("product added")
println(product.productIdentifier)
println(product.localizedTitle)
println(product.localizedDescription)
println(product.price)
list.append(product as! SKProduct)
}
}
func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue!) {
println("transactions restored")
var purchasedItemIDS = []
for transaction in queue.transactions {
var t: SKPaymentTransaction = transaction as! SKPaymentTransaction
let prodID = t.payment.productIdentifier as String
switch prodID {
case "IAP id here":
//Right here is where you should put the function that you want to execute when your in app purchase is complete
default:
println("IAP not setup")
}
}
var alert = UIAlertView(title: "Thank You", message: "Your purchase(s) were restored. You may have to restart the app before banner ads are removed.", delegate: nil, cancelButtonTitle: "OK")
alert.show()
}
func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {
println("add paymnet")
for transaction:AnyObject in transactions {
var trans = transaction as! SKPaymentTransaction
println(trans.error)
switch trans.transactionState {
case .Purchased, .Restored:
println("buy, ok unlock iap here")
println(p.productIdentifier)
let prodID = p.productIdentifier as String
switch prodID {
case "IAP id here":
//Here you should put the function you want to execute when the purchase is complete
var alert = UIAlertView(title: "Thank You", message: "You may have to restart the app before the banner ads are removed.", delegate: nil, cancelButtonTitle: "OK")
alert.show()
default:
println("IAP not setup")
}
queue.finishTransaction(trans)
break;
case .Failed:
println("buy error")
queue.finishTransaction(trans)
break;
default:
println("default")
break;
}
}
}
func finishTransaction(trans:SKPaymentTransaction)
{
println("finish trans")
}
func paymentQueue(queue: SKPaymentQueue!, removedTransactions transactions: [AnyObject]!)
{
println("remove trans");
}
Next you must name the node you need to do the iAP
whateverYourNodeIs.name = "inAppPurchaseNode"
Finally, do this in the touchesBegan
let touch = touches.first as? UITouch
let positionInScene = touch!.locationInNode(self)
let touchedNode = self.nodeAtPoint(positionInScene)
if let name = touchedNode.name {
if name == "inAppPurchaseNode" {
for product in list {
var prodID = product.productIdentifier
if(prodID == "iAp id here") {
p = product
buyProduct() //This is one of the functions we added earlier
break;
}
}
}
}
You will also want this in your touches began to restore the purchases using a different node.
if let name = touchedNode.name {
if name == "restore" {
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
}
In-App Purchases Swift Game
You can find a good tutorial here at the Apple Docs: Here
Hope that helps,
Julian
In app purchase in SKScene not working?
After a good few weeks of work, I found out that you must have your Paid Applications agreement filled out completely and accepted in order for your code and products to work. Approval can take a few days, then you're in the clear.
In-app-purchase logic in spritekit
//for non-consumable product you have to add following code in your application
//function checks whether user purchase a non-consumable or not
/*
change all function acc to your game
*/
-(void)setDone:(Boolean)status
{
[_urnsuserDefault setBool:status forKey:@“done];
[_urnsuserDefault synchronize];
}
-(Boolean)getDone
{
Boolean status=[_urnsuserDefault boolForKey:@"done"];
return status;
}
//if user already purchase non-consumable or not (check for Restore if user purchase non-consumable product);
-(void)checkForRestore
{
if([self getDone])
{
//if user successfully purchase a in app item
UIAlertView *productAlertPur = [[UIAlertView alloc]
initWithTitle:@"Restored"
message:@“your” msg
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"Ok", nil];
[productAlertPur show];
}
else
{
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
}
-(void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
UIAlertView * removedAlert = [[UIAlertView alloc]
initWithTitle:nil message:[NSString stringWithFormat:@"Restoration failed as %@.",error.localizedDescription] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[removedAlert show];
}
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
purchasedItemIDs = [[NSMutableArray alloc] init];
if(queue.transactions.count==0){
UIAlertView *noproductAlert = [[UIAlertView alloc]
initWithTitle:@"Restored"
message:@"No Purchases to Restore"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"Ok", nil];
[noproductAlert show];
}
else{
if(![self getDone])
{
NSString *productID = @“company.game.productid;
[purchasedItemIDs addObject:productID];
UIAlertView *restoredAlert = [[UIAlertView alloc]
initWithTitle:@"Restored"
message:[NSString stringWithFormat:@"Math Lab Restored successfully."]
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"Ok", nil];
[restoredAlert show];
[self viewWillAppear:YES];
[self setDone:TRUE];
}
}
}
Related Topics
Swift Firebase Using an Unspecified Index
Bringing iOS Frameworks Through Carthage in Xcode 12.0
How to Open Your App's Settings (Inside the Settings App) with Swift (iOS 11)
Send Mail with File Attachment
Rotate a Text View and Its Frame in Swiftui
How to Convert an Anykeypath to a Writablekeypath
Why Is Deinit Not Called Until Uiview Is Added to Parent Again
How to Add a Loading View for Apple Watch
Numeric Types Don't Automatically Bridge to Nsnumber in Pure Swift on Ubuntu Linux
Play Sound with a Little Delay
Create a Loading Image/ Activity Indicator, Until the Image Is Shown in the Screen in Swift
Type of Expression Is Ambiguous Without More Context in Xcode 11
Repeating Action Continuously in Swiftui
Checking User Location Permission Status on iOS 14
How to Apply a Grace Time Using Rx
Check If a Character Is Lowercase or Uppercase