ios - sierra - Swift, spritekit: en el código de compra de la aplicación se ejecuta, ¿NADA sucede?
xcode mac español (1)
Ok, entonces estoy trabajando en Swift y solo necesito ayuda. He seguido 4 tutoriales diferentes sobre cómo implementar compras de aplicaciones en el kit de sprites con Swift, código copiado textualmente, y nada funciona para mí.
Estos son los pasos que he tomado:
Ido en Itunes Connect y creado una compra en la aplicación en el registro de mi aplicación. El ID de producto de mi compra en la aplicación es
"GameOverSaveSavior"
En Xcode, activé la función de compra en la aplicación de mi aplicación, me aseguré de que mi equipo esté configurado en mi cuenta y me aseguré de que mi identificador de paquete en la información esté configurado en el identificador de paquete de mi aplicación en iTunes Connect
Antes de escribir cualquier código, he
import StoreKit
en mi archivo GameScene.swift
En cuanto al código, esto es lo que he hecho:
(1) En Gamescene.swift, al final de mi función didMoveToView
, tengo:
// Set IAPS
if(SKPaymentQueue.canMakePayments()) {
println("IAP is enabled, loading")
var productID:NSSet = NSSet(objects: "GameOverSaveSavior")
var request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as Set<NSObject>)
request.delegate = self
request.start()
} else {
println("please enable IAPS")
}
Esto produce "IAP is enabled, loading"
cuando se ejecuta la aplicación.
(2) En GameScene.swift, dentro de la clase pero fuera de didMoveToView
, tengo todas las funciones y variables que otros han utilizado en las compras de aplicaciones:
var list = [SKProduct]()
var p = SKProduct()
func purchaseMade() {
println("they bought it!")
}
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 "GameOverSaveSavior":
purchaseMade()
//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 "GameOverSaveSavior":
//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");
}
Esto envía "product request"
a la consola cuando se ejecuta la aplicación.
(3) En GameScene.swift, en my touchesBegan
func, tengo lo siguiente para cuando se toca el botón derecho:
//In app purchase
if touchedNode == saveMeBtn {
println("button touched!")
for product in list {
var prodID = product.productIdentifier
if(prodID == "GameOverSaveSavior") {
p = product
buyProduct() //This is one of the functions we added earlier
break;
}
}
Esto produce "button touched!"
cuando se toca el botón.
No sé lo que estoy haciendo mal. El código se compila sin errores, pero no ocurre nada cuando se toca mi botón. No hay ninguna alerta pidiéndole al usuario que inicie sesión o que compre algo, nada. Principalmente, he seguido esta pregunta: en la compra de aplicaciones en SKScene
¿Hay algo más que debería haber hecho antes de escribir el código? ¿Me estoy perdiendo algo en mi código?
Creo que puedo ayudarte:
Tuve tu problema en el pasado. Y otro similar que arreglé aquí: Mi IAP no funciona. Errores en func Paymentqueue
Aquí está la solución que había encontrado:
Borrar
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
donde sea que lo tenga y lo ponga una vez (SOLAMENTE UNA VEZ) en un lugar donde se ejecutará cada vez que se inicie su aplicación (lo puse en viewDidLoad ()).
Esto verificará todas las transacciones pendientes y las finalizará una vez que la aplicación se haya cargado, eliminando así cualquier posible error antes de que los usuarios activen un IAP.
(Si esta respuesta te ayudó, no te olvides de votar al alza;))
PD: Además, este no era mi problema, pero asegúrese de terminarTransaction () para cada PurchaseState, como aquí:
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("Add Payment")
for transaction:AnyObject in transactions{
let trans = transaction as! SKPaymentTransaction
print(trans.error)
switch trans.transactionState{
case .Purchased:
print("IAP unlocked")
print(p.productIdentifier)
let prodID = p.productIdentifier as String
switch prodID{
case "IAP id":
print("Keep on")
keepOn()
default:
print("IAP not setup")
}
queue.finishTransaction(trans)
break
case .Failed:
print ("Buy error")
queue.finishTransaction(trans)
break
default:
print("default: Error")
break
}
}
}
Nunca olvides esto:
queue.finishTransaction(trans)
Y crea un caso separado para .Restored.