I made a game using Xcode 7 and SpriteKit in Swift, and I finished it. After I sent it to iTunes Connect, Apple rejected it and they sent me a message, they said that the problem is related Restore Purchase, but I put it in the same purchase button, so I made a button that has two functions: 1. Make a purchase, 2. Restore the purchase.
When I tested it, it worked perfectly, and when users have to restore the purchase, they no longer pay. I don't know if this is acceptable from Apple. Or check my code if I forgot to put something!
Message:
From Apple
Missing recovery mechanism
We have found that your application offers an In-App Purchase (s) that can be restored, but does not include the “Restore Purchases” function to allow users to restore previously purchased purchases (s) in the application, as indicated in the “Restoring Purchasing Products” Section "Programming Guides for App Purchases
"Users restore transactions in order to maintain access to already purchased content. For example, when upgrading to a new phone, they don’t lose all the items they purchased on the old phone. Turn on some mechanism in your mechanism so that the user restores his purchases, for example, a button "Restore purchases."
In-App Purchase, " " , " "" ". .
, , :
override func viewDidLoad() {
super.viewDidLoad()
func addTransactionObserver() {
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
func removeTransactionObserver() {
SKPaymentQueue.defaultQueue().removeTransactionObserver(self)
}
}
@IBAction func removeAds(sender: UIButton) {
print("Remove Ads Button pressed")
for product in list {
let prodID = product.productIdentifier
if(prodID == "Squares.RemoveAds") {
p = product
buyProduct()
break;
}
}
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}
override func prefersStatusBarHidden() -> Bool {
return true
}
var list = [SKProduct]()
var p = SKProduct()
func buyProduct() {
print("Buy" + p.productIdentifier)
let pay = SKPayment(product: p)
SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment)
}
func productsRequest(request: SKProductsRequest, didReceiveResponse 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 as SKProduct)
}
removeAdsButton.enabled = true
removeAdsIPhone6Plus.enabled = true
}
func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) {
print("Transactions Restored")
var purchasedItemIDS = []
for transaction in queue.transactions {
let t: SKPaymentTransaction = transaction as SKPaymentTransaction
let prodID = t.payment.productIdentifier as String
switch prodID {
case ProductID.removeAds:
print("Remove Ads")
Ads.removeAllAds()
case ProductID.removeAds:
print("Remove Ads for iPhone 6 Plus")
Ads.removeAllAds()
default:
print("IAP not setup")
}
}
}
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("Buy, Ok unlock Squares here")
print(p.productIdentifier)
let prodID = p.productIdentifier as String
switch prodID {
case ProductID.removeAds:
print("Remove Ads")
Ads.removeAllAds()
case ProductID.removeAds:
print("Remove Ads for iPhone 6 Plus")
Ads.removeAllAds()
default:
print("IAP not Setup")
}
queue.finishTransaction(trans)
break;
case .Failed:
print("Buy Error")
queue.finishTransaction(trans)
break;
default:
print("Default")
break;
}
}
}
func finishTransaction(trans:SKPaymentTransaction){
print("Finish Transaction")
}
func paymentQueue(queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {
print("Remove Transaction")
}
}
, .