In app purchase within SKScene using SpriteNode? - swift

I'm using this code to unlock a scene once a purchase has been made. My first question is whether the code is correct in that the purchase will work. My second question is that I'm asking the purchase to happen when a sprite node is pressed, am I calling the correct function to happen in touches began? All of the code below is within an SKScene
var list = [SKProduct]()
var p = SKProduct()
override func didMoveToView(view: SKView) {
if(SKPaymentQueue.canMakePayments()) {
println("IAP is enabled, loading")
var productID:NSSet = NSSet(objects: "_Scene1_Unlock")
var request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as Set<NSObject>)
request.delegate = self
request.start() } else {
println("please enable IAPS") }
}
func addScene1() {
println("scene1 added") }
func RestorePurchases() {
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().restoreCompletedTransactions() }
func btnAddScene1() {
for product in list {
var prodID = product.productIdentifier
if(prodID == "_Scene1_Unlock") {
p = product
buyProduct()
break; } } }
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 "_Scene1_Unlock":
println("remove ads")
addScene1()
default:
println("IAP not setup")}}}
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:
println("buy, ok unlock iap here")
println(p.productIdentifier)
let prodID = p.productIdentifier as String
switch prodID {
case "_Scene1_Unlock":
println("remove ads")
addScene1()
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") }
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch in (touches as! Set<UITouch>) {
let location = touch.locationInNode(self)
if self.nodeAtPoint(location) == self.stopScene1 {
btnAddScene1()
}

Related

SwiftUI app freezing when using multiple product identifiers in StoreKit

I'm currently learning Swift and following some tutorials but I'm stuck on a StoreKit issue.
The code works when I provide a single productIdentifier, but when I provide more than 1 in the Set, the entire app hangs on loading. This is in the iOS Simulator, and on a device. I've got 2 identifiers in the set, and both of these work individually, but not at the same time. My code looks the same as the original tutorial (video) so I don't know where I'm going long.
Entire Store.swift file below. Problem appears to be in the fetchProducts function, but I'm not sure. Can anyone point me in the right direction?
import StoreKit
typealias FetchCompletionHandler = (([SKProduct]) -> Void)
typealias PurchaseCompletionHandler = ((SKPaymentTransaction?) -> Void)
class Store: NSObject, ObservableObject {
#Published var allRecipes = [Recipe]() {
didSet {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
for index in self.allRecipes.indices {
self.allRecipes[index].isLocked = !self.completedPurchases.contains(self.allRecipes[index].id)
}
}
}
}
private let allProductIdentifiers = Set(["com.myname.ReceipeStore.test", "com.myname.ReceipeStore.test2"])
private var completedPurchases = [String]()
private var productsRequest: SKProductsRequest?
private var fetchedProducts = [SKProduct]()
private var fetchCompletionHandler: FetchCompletionHandler?
private var purchaseCompletionHandler: PurchaseCompletionHandler?
override init() {
super.init()
startObservingPaymentQueue()
fetchProducts { products in
self.allRecipes = products.map { Recipe(product: $0) }
}
}
private func startObservingPaymentQueue() {
SKPaymentQueue.default().add(self)
}
private func fetchProducts(_ completion: #escaping FetchCompletionHandler) {
guard self.productsRequest == nil else { return }
fetchCompletionHandler = completion
productsRequest = SKProductsRequest(productIdentifiers: allProductIdentifiers)
productsRequest!.delegate = self
productsRequest!.start()
}
private func buy(_ product: SKProduct, competion: #escaping PurchaseCompletionHandler) {
purchaseCompletionHandler = competion
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment)
}
}
extension Store {
func product(for identififier: String) -> SKProduct? {
return fetchedProducts.first(where: { $0.productIdentifier == identififier })
}
func purchaseProduct(_ product: SKProduct) {
buy(product) { _ in }
}
}
extension Store: SKPaymentTransactionObserver {
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
var shouldFinishTransactions = false
switch transaction.transactionState {
case .purchased, .restored:
completedPurchases.append(transaction.payment.productIdentifier)
shouldFinishTransactions = true
case .failed:
shouldFinishTransactions = true
case .deferred, .purchasing:
break
#unknown default:
break
}
if shouldFinishTransactions {
SKPaymentQueue.default().finishTransaction(transaction)
DispatchQueue.main.async {
self.purchaseCompletionHandler?(transaction)
self.purchaseCompletionHandler = nil
}
}
}
}
}
// loading products from the store
extension Store: SKProductsRequestDelegate {
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
let loadedProducts = response.products
let invalidProducts = response.invalidProductIdentifiers
guard !loadedProducts.isEmpty else {
print("Could not load the products!")
if !invalidProducts.isEmpty {
print("Invalid products found: \(invalidProducts)")
}
productsRequest = nil
return
}
// cache the feteched products
fetchedProducts = loadedProducts
// notify anyone waiting on the product load (swift UI view)
DispatchQueue.main.async {
self.fetchCompletionHandler?(loadedProducts)
self.fetchCompletionHandler = nil
self.productsRequest = nil
}
}
}```
It looks like you're running all of your requests on the main DispatchQueue, this will block other main queue work until completed. You should consider handling some of these tasks with a custom concurrent queue. This bit of sample code should get the ball rolling.
func requestProducts(_ productIdentifiers: Set<ProductIdentifier>, handler: #escaping ProductRequestHandler) {
// Set request handler
productRequest?.cancel()
productRequestHandler = handler
// Request
productRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
productRequest?.delegate = self
productRequest?.start()
}
func requestPrices() {
// Retry interval, 5 seconds, set this to your liking
let retryTimeOut = 5.0
var local1: String? = nil
var local2: String? = nil
let bundleIdentifier = Bundle.main.bundleIdentifier!
let queue = DispatchQueue(label: bundleIdentifier + ".IAPQueue", attributes: .concurrent)
// Request price
queue.async {
var trying = true
while(trying) {
let semaphore = DispatchSemaphore(value: 0)
requestProducts(Set(arrayLiteral: SettingsViewController.pID_1000Credits, SettingsViewController.pID_2000Credits)) { (response, error) in
local1 = response?.products[0].localizedPrice
local2 = response?.products[1].localizedPrice
semaphore.signal()
}
// We will keep checking on this thread until completed
_ = semaphore.wait(timeout: .now() + retryTimeOut)
if(local2 != nil) { trying = false }
}
// Update with main thread once request is completed
DispatchQueue.main.async {
self.price1 = local1 ?? "$0.99"
self.price2 = local2 ?? "$1.99"
}
}
}
extension SKProduct {
// Helper function, not needed for this example
public var localizedPrice: String? {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = self.priceLocale
return formatter.string(from: self.price)
}

Password for in app purchases setup says Apple ID you entered couldn't be font even if its right

When ever i type in my password after the prompt goes up and it ask me for me password even if its correct it says. password can't be fond "Apple ID you entered couldn't be fond of your password was incorrect. and the Remove adds button doesn't do anything
Code:
import Foundation
import AVFoundation
import SpriteKit
import GameKit
import UIKit
import StoreKit
class ThirdScene: SKScene, SKPaymentTransactionObserver, SKProductsRequestDelegate {
let RemoveaddsButton = SKSpriteNode(imageNamed: "PlayAltenative")
let RestorePurchases = SKSpriteNode(imageNamed: "StopButton")
var iAdLabel = SKLabelNode()
override func didMoveToView(view: SKView) {
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
//----------------------------------------------
iAdLabel.text = "I am An Advertisment"
iAdLabel.fontSize = 20
iAdLabel.zPosition = 20
iAdLabel.fontColor = SKColor.whiteColor()
iAdLabel.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height * 0.70)
self.addChild(iAdLabel)
//-----------------------------------------------------------------------
self.RemoveaddsButton.position = CGPoint(x: self.frame.size.width * 0.70, y: self.frame.size.height * 0.20)
RemoveaddsButton.zPosition = 100
RemoveaddsButton.size = CGSize(width: 115, height: 170)
self.addChild(self.RemoveaddsButton)
//-----------------------------------------------------
self.RestorePurchases.position = CGPoint(x: self.frame.size.width * 0.10, y: self.frame.size.height * 0.20)
RestorePurchases.zPosition = 100
RestorePurchases.size = CGSize(width: 115, height: 170)
self.addChild(self.RestorePurchases)
if(SKPaymentQueue.canMakePayments()) {
println("IAP is enabled, loading")
var productID:NSSet = NSSet(objects: "SkateLinesNolliePackage")
var request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as Set<NSObject>)
request.delegate = self
request.start()
} else {
println("please enable IAPS")
}
}
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 removeAd() {
iAdLabel.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height * 9.70)
}
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 "SkateLinesNolliePackage":
removeAd()
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 "SkateLinesNolliePackage":
//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");
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch: AnyObject in touches {
name = "RemoveaddsButton"
let location = touch.locationInNode(self)
if self.nodeAtPoint(location) == self.RemoveaddsButton {
for product in list {
var prodID = product.productIdentifier
if(prodID == "SkateLinesNolliePackage") {
p = product
buyProduct() //This is one of the functions we added earlier
break;
}
}
}
let location1 = touch.locationInNode(self)
if self.nodeAtPoint(location1) == self.RestorePurchases {
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
}
}
}
It sounds like you need a sandbox tester. Go to iTunes Connect, click on my apps, then click on the app that you made. Next, click prerelease. After that, click on internal testers. After you do that, click on users and roles. Then, click sandbox testers and create a tester with a fake email and password that is not used in any other apple id. The in app purchase should then work with that id.

in app purchase in SKScene

Is it possible to implement an in-app purchase within the SKScene? If so, how? I'm trying to use a SKSpriteNode as a 'buy' button with no luck. I'm not sure whether the code needs to go in the SKScene or the view controller. I've looked at loads of tutorials, but they all seem to be aimed at single view applications rather than in SpriteKit.
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)
}
}

Will my app get rejected if the user has to close and open the app to unlock the in app purchase?

Sorry for all the code I just want to get this right. I have three different in app purchases and this is my code in the GameViewController. I called the functions in my viewDidLoad() function. Does anyone see anything wrong with the code?
EDIT:
override func viewDidLoad() {
super.viewDidLoad()
callthis()
callthis2()
callthis3()
}
func callthis() {
if(SKPaymentQueue.canMakePayments()) {
println("IAP is enabled, loading")
var productID:NSSet = NSSet(object: "unlockLevelTwo")
var request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as Set<NSObject>)
request.delegate = self
request.start()
} else {
println("please enable IAPS")
}
}
func callthis2() {
if(SKPaymentQueue.canMakePayments()) {
println("IAP is enabled, loading")
var productID:NSSet = NSSet(object: "unlockLevelThree")
var request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as Set<NSObject>)
request.delegate = self
request.start()
} else {
println("please enable IAPS")
}
}
func callthis3() {
if(SKPaymentQueue.canMakePayments()) {
println("IAP is enabled, loading")
var productID:NSSet = NSSet(object: "unlockEverything")
var request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as Set<NSObject>)
request.delegate = self
request.start()
} else {
println("please enable IAPS")
}
}
func RestorePurchases() {
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
println("Can't make 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!) {
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 request(request: SKRequest!, didFailWithError error: NSError!) {
println("Error fetching product info")
}
func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {
println("Received Payment Transaction Response from Apple");
for transaction:AnyObject in transactions {
var trans = transaction as! SKPaymentTransaction
println(trans.error)
switch trans.transactionState {
case .Purchased, .Restored:
let prodID = trans.payment.productIdentifier as String
switch prodID {
case "unlockLevelTwo":
println("unlocksleveltwo")
NSUserDefaults().setBool(true, forKey: "Leavel2")
gameScene.unlockLevelTwoPlease()
case "unlockLevelThree":
println("unlocklevelthree")
NSUserDefaults().setBool(true, forKey: "Leavel3")
gameScene.unlockLevelThreePlease()
case "unlockEverything":
println("unlockeverything")
NSUserDefaults().setBool(true, forKey: "Leavel2")
gameScene.unlockLevelTwoPlease()
NSUserDefaults().setBool(true, forKey: "Leavel3")
gameScene.unlockLevelThreePlease()
defaults.setBool(true , forKey: "removeAdsPurchased")
default:
println("unlocksEverything")
}
queue.finishTransaction(trans)
break;
case .Failed:
println("Purchased Failed");
queue.finishTransaction(trans)
break;
default:
println("default")
break;
}
}
}
func finishTransaction(trans:SKPaymentTransaction) {
println("finish trans")
SKPaymentQueue.defaultQueue().finishTransaction(trans)
}
func paymentQueue(queue: SKPaymentQueue!, removedTransactions transactions: [AnyObject]!) {
println("remove trans");
}
Then in my GameScene.swift file I do this:
if node.name == "unlockleveltwobutton" {
for product in viewController.list {
var prodID = product.productIdentifier
if(prodID == "unlockLevelTwo") {
viewController.p = product
viewController.buyProduct()
break;
}
}
runAction(menuAudioPlayer)
}
if node.name == "unlocklevelthreebutton" {
for product in viewController.list {
var prodID = product.productIdentifier
if(prodID == "unlockLevelThree") {
viewController.p = product
viewController.buyProduct()
break;
}
}
runAction(menuAudioPlayer)
}
if node.name == "specialdeal" {
for product in viewController.list {
var prodID = product.productIdentifier
if(prodID == "unlockEverything") {
viewController.p = product
viewController.buyProduct()
break;
}
}
runAction(menuAudioPlayer)
}

Swift Sprite Kit In App Purchase

I have a button in an SKScene (using Swift) -- "Add Puzzles"
When the user clicks this button, I want to go to a UIView Controller or UI Scene so that I can implement In App Purchase code... (SkScenes are subsets of UIViews and cannot run the code...)
Does anyone have a basic idea how to do this...
I am a little inexperienced at this... I have used cocos2d and now Sprite Kit and have always set everything up manually and have very little experience with .xib files and view Controllers...
Does anyone know the basic idea of how to do this? Thanks for any help!
ANDY
You can set-up In-App-Purchases inside of an SKScene, You may need to tweak some code but it will work. Here's an example
import Spritekit
import Storekit
class Store:SKScene, SKProductsRequestDelegate, SKPaymentTransactionObserver {
override func didMoveToView {
// Set IAPS
if(SKPaymentQueue.canMakePayments()) {
println("IAP is enabled, loading")
var productID:NSSet = NSSet(objects: "bundle id", "bundle id")
var request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID)
request.delegate = self
request.start()
} else {
println("please enable IAPS")
}
}
// 2
func btnRemoveAds() {
for product in list {
var prodID = product.productIdentifier
if(prodID == "bundle id") {
p = product
buyProduct()
break;
}
}
}
// 3
func btnAddCoins() {
for product in list {
var prodID = product.productIdentifier
if(prodID == "bundle id") {
p = product
buyProduct()
break;
}
}
}
// 4
func removeAds() {
println("ads removed")
}
// 5
func addCoins() {
println("added 50 coins")
}
// 6
func RestorePurchases() {
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}
var list = [SKProduct]()
var p = SKProduct()
// 2
func buyProduct() {
println("buy " + p.productIdentifier)
var pay = SKPayment(product: p)
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment)
}
//3
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)
}
}
// 4
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 "bundle id":
println("remove ads")
removeAds()
case "bundleid":
println("add coins to account")
addCoins()
default:
println("IAP not setup")
}
}
}
// 5
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:
println("buy, ok unlock iap here")
println(p.productIdentifier)
let prodID = p.productIdentifier as String
switch prodID {
case "bundle id":
println("remove ads")
removeAds()
case "bundle id":
println("add coins to account")
addCoins()
default:
println("IAP not setup")
}
queue.finishTransaction(trans)
break;
case .Failed:
println("buy error")
queue.finishTransaction(trans)
break;
default:
println("default")
break;
}
}
}
// 6
func finishTransaction(trans:SKPaymentTransaction)
{
println("finish trans")
}
//7
func paymentQueue(queue: SKPaymentQueue!, removedTransactions transactions: [AnyObject]!)
{
println("remove trans");
}
You would call the removeAdsButton() or whatever when you want to make a purchase.