This seems to be a common problem from my research
This is all done on a real device.
My app buys the In App Purchase, but when I come to restore the In App Purchase it does not react.
Following this,
@IBAction func RestoreItem(_ sender: Any) {
SKPaymentQueue.default().restoreCompletedTransactions()
print("RESTORING PURCHASES")
}
it is supposed to call the products request
then payment queue
functions.
I have read that if the iTunes Account does not contain the purchases that are not called.
If I run the app and purchase each item the app purchases ok and says these have been purchased before so it knows the purchase history
What I can not understand is why, if it knows the items have been purchased it does not react after calling the function (as seen above).
If I log out of my iTunes Account completely on my device and trigger the action above it asks me to log in to my account. I do this (the same account where I previously purchased) and it does not trigger the product request
(I have NSlog
statements all over to see what state I am at)
Any thoughts as i have been struggling with this for days. thanks
I have included code below, this works for purchasing (just for reference).
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
print("product request")
let myProduct = response.products
for product in myProduct {
print("product added")
print(product.productIdentifier)
print(product.localizedTitle)
print(product.localizedDescription)
print(product.price)
list.append(product)
}
}
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("add payment")
for transaction: AnyObject in transactions {
let trans = transaction as! SKPaymentTransaction
print(trans.error as Any)
switch trans.transactionState {
case SKPaymentTransactionState.purchased:
print("buy ok, unlock IAP HERE")
print(p.productIdentifier)
let prodID = p.productIdentifier
switch prodID {
case "com.clivedancey.social":
print("Social Reality Unlocked")
outBuySocial.setTitle("Social Reality Enabled", for: UIControlState.normal)
SocialReality()
case "com.clivedancey.inapp":
print("MAIN UPGRADE UNLOCKED")
outBuyMain.setTitle(" Main Upgrade Complete", for: UIControlState.normal)
mainunlock()
default:
print("IAP not setup")
}
queue.finishTransaction(trans)
case SKPaymentTransactionState.restored:
print("buy ok, unlock IAP HERE")
print(p.productIdentifier)
let prodID = p.productIdentifier
switch prodID {
case "com.clivedancey.social":
print("Social Reality Unlocked")
outBuySocial.setTitle("Social Reality Enabled", for: UIControlState.normal)
SocialReality()
outTransactionLabel.text = " Purchases restored"
case "com.clivedancey.inapp":
print("MAIN UPGRADE UNLOCKED")
outBuyMain.setTitle(" Main Upgrade Complete", for: UIControlState.normal)
outTransactionLabel.text = " Purchases restored1"
mainunlock()
default:
print("IAP not setup")
}
queue.finishTransaction(trans)
case.failed:
print("buy error")
queue.finishTransaction(trans)
break
default:
print("Default")
break
}
}
}
A few things. First - hopefully not important - is your use of "react" in but when I come to restore the In App Purchase it does not react. I hope you don't mean that a breakpoint is never hit.
My StoreKit code has two things I'm not seeing in the code you posted.
(1) In viewDidLoad
I check for purchases and store it:
func fetchAvailableProducts() {
productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers as! Set<String>)
productsRequest.delegate = self
productsRequest.start()
}
public func productsRequest (_ request:SKProductsRequest, didReceive response:SKProductsResponse) {
if (response.products.count > 0) {
iapProducts = response.products
}
}
Of note is setting the view controller as a delegate - something I don't see in your code. (The logic sounds good though.)
(2) My restore purchases has an extra line of code:
func restorePurchases() {
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()
}