如何使用 Xcode 7 和 Swift 中的 SpriteKit 修复 iOS 应用程序中的恢复购买?
How to fix Restore Purchase in iOS application, using Xcode 7 and SpriteKit in Swift?
我在 Swift 中使用 Xcode 7 和 SpriteKit 制作了一个游戏并完成了它。在我将它提交到 iTunes Connect 后,Apple 拒绝了它,他们给我发了一条消息,他们说问题出在 Restore Purchase
,但我把它放在与购买相同的按钮中,所以我制作了一个具有两个功能的按钮:
1. 进行购买,
2. 恢复购买。
当我测试它时,它运行良好,当用户必须恢复购买时,他们不再支付。我不知道这是否可以被 Apple 接受。或者如果我忘了放东西,请检查我的代码!
消息是:
From Apple
Missing restore mechanism
We found that your app offers In-App Purchase(s) that can be restored but does not include a “Restore Purchases" feature to allow users to restore the previously purchased In-App Purchase(s), as specified in the “Restoring Purchase Products” section of the In-App Purchase Programming Guide
"Users restore transactions to maintain access to content they’ve already purchased. For example, when they upgrade to a new phone, they don’t lose all of the items they purchased on the old phone. Include some mechanism in your app to let the user restore their purchases, such as a Restore Purchases button."
To restore previously purchased In-App Purchase products, it would be appropriate to provide a "Restore" button and initiate the restore process when the "Restore" button is tapped by the user. Including restore in the purchase button is not a sufficient restore mechanism.
我使用的代码是:
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().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}
override func prefersStatusBarHidden() -> Bool {
return true
}
//Remove Ads Payment
var list = [SKProduct]()
var p = SKProduct()
//Squares.RemoveAds
func buyProduct() {
print("Buy" + p.productIdentifier)
let pay = SKPayment(product: p)
////SKPaymentQueue.defaultQueue().addTransactionObserver(self)
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")
}
}
希望您的贡献对我有所帮助。
您可能只需要在屏幕上放置一个按钮供用户按下,然后将其连接到@IBAction func RestorePurchases
我已经包含了 Xcode 7.0、iOS 9.0 和 Swift 2.0 的默认 IAP 使用正确的字符串更改 "com.dname.YourApp.removeAds":)
//
// IAPViewController.swift
//
import UIKit
import StoreKit
class IAPViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver{
let userDefaults = NSUserDefaults.standardUserDefaults()
//@IBOutlet var lblAd: UILabel!
// @IBOutlet var lblCoinAmount: UILabel!
@IBOutlet var removeAds: UIButton!
//@IBOutlet var outAddCoins: UIButton!
//var coins = 50
// 1
override func viewDidLoad() {
super.viewDidLoad()
removeAds.enabled = false
// outAddCoins.enabled = false
// Set IAPS
if(SKPaymentQueue.canMakePayments()) {
print("IAP is enabled, loading")
let productID:NSSet = NSSet(objects: "com.dname.YourApp.removeAds")
let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>)
request.delegate = self
request.start()
} else {
print("please enable IAPS")
}
}
// 2
@IBAction func btnRemoveAds(sender: UIButton) {
for product in list {
let prodID = product.productIdentifier
if(prodID == "com.dname.YourApp.removeAds") {
p = product
buyProduct()
break;
}
}
}
/*
// 3
@IBAction func btnAddCoins(sender: UIButton) {
for product in list {
var prodID = product.productIdentifier
if(prodID == "com.dname.YourApp.addcoins") {
p = product
buyProduct()
break;
}
}
}
*/
/*
// 4
func removeAds() {
lblAd.removeFromSuperview()
}
*/
/*
// 5
func addCoins() {
coins = coins + 50
lblCoinAmount.text = "\(coins)"
}
*/
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func RestorePurchases(sender: UIButton) {
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}
var list = [SKProduct]()
var p = SKProduct()
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)
//println(product.price)
list.append(product )
}
removeAds.enabled = true
//outAddCoins.enabled = true
}
func buyProduct() {
print("buy " + p.productIdentifier)
let pay = SKPayment(product: p)
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment)
}
func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) {
print("transactions restored")
// var purchasedItemIDS = []
for transaction in queue.transactions {
let t: SKPaymentTransaction = transaction
let prodID = t.payment.productIdentifier as String
switch prodID {
case "com.dname.YourApp.removeAds":
//Set the user default to not show ads
userDefaults.setObject(1, forKey: "noAds")
userDefaults.synchronize()
print("remove ads")
//removeAds()
case "com.dname.YourApp.addcoins":
print("add coins to account")
//addCoins()
default:
print("IAP not setup")
}
}
}
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("add paymnet")
for transaction:AnyObject in transactions {
let trans = transaction as! SKPaymentTransaction
print(trans.error)
switch trans.transactionState {
case .Purchased:
print("buy, ok unlock iap here")
print(p.productIdentifier)
let prodID = p.productIdentifier as String
switch prodID {
case "com.dname.YourApp.removeAds":
print("remove ads")
//Set the user default to not show ads
userDefaults.setObject(1, forKey: "noAds")
userDefaults.synchronize()
//removeAds()`enter code here`
case "com.dname.YourApp.addcoins":
print("add coins to account")
//addCoins()
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 trans")
SKPaymentQueue.defaultQueue().finishTransaction(trans)
}
func paymentQueue(queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {
print("Remove Transaction")
}
}
我在 Swift 中使用 Xcode 7 和 SpriteKit 制作了一个游戏并完成了它。在我将它提交到 iTunes Connect 后,Apple 拒绝了它,他们给我发了一条消息,他们说问题出在 Restore Purchase
,但我把它放在与购买相同的按钮中,所以我制作了一个具有两个功能的按钮:
1. 进行购买,
2. 恢复购买。
当我测试它时,它运行良好,当用户必须恢复购买时,他们不再支付。我不知道这是否可以被 Apple 接受。或者如果我忘了放东西,请检查我的代码!
消息是:
From Apple
Missing restore mechanism
We found that your app offers In-App Purchase(s) that can be restored but does not include a “Restore Purchases" feature to allow users to restore the previously purchased In-App Purchase(s), as specified in the “Restoring Purchase Products” section of the In-App Purchase Programming Guide
"Users restore transactions to maintain access to content they’ve already purchased. For example, when they upgrade to a new phone, they don’t lose all of the items they purchased on the old phone. Include some mechanism in your app to let the user restore their purchases, such as a Restore Purchases button."
To restore previously purchased In-App Purchase products, it would be appropriate to provide a "Restore" button and initiate the restore process when the "Restore" button is tapped by the user. Including restore in the purchase button is not a sufficient restore mechanism.
我使用的代码是:
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().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}
override func prefersStatusBarHidden() -> Bool {
return true
}
//Remove Ads Payment
var list = [SKProduct]()
var p = SKProduct()
//Squares.RemoveAds
func buyProduct() {
print("Buy" + p.productIdentifier)
let pay = SKPayment(product: p)
////SKPaymentQueue.defaultQueue().addTransactionObserver(self)
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")
}
}
希望您的贡献对我有所帮助。
您可能只需要在屏幕上放置一个按钮供用户按下,然后将其连接到@IBAction func RestorePurchases
我已经包含了 Xcode 7.0、iOS 9.0 和 Swift 2.0 的默认 IAP 使用正确的字符串更改 "com.dname.YourApp.removeAds":)
//
// IAPViewController.swift
//
import UIKit
import StoreKit
class IAPViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver{
let userDefaults = NSUserDefaults.standardUserDefaults()
//@IBOutlet var lblAd: UILabel!
// @IBOutlet var lblCoinAmount: UILabel!
@IBOutlet var removeAds: UIButton!
//@IBOutlet var outAddCoins: UIButton!
//var coins = 50
// 1
override func viewDidLoad() {
super.viewDidLoad()
removeAds.enabled = false
// outAddCoins.enabled = false
// Set IAPS
if(SKPaymentQueue.canMakePayments()) {
print("IAP is enabled, loading")
let productID:NSSet = NSSet(objects: "com.dname.YourApp.removeAds")
let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>)
request.delegate = self
request.start()
} else {
print("please enable IAPS")
}
}
// 2
@IBAction func btnRemoveAds(sender: UIButton) {
for product in list {
let prodID = product.productIdentifier
if(prodID == "com.dname.YourApp.removeAds") {
p = product
buyProduct()
break;
}
}
}
/*
// 3
@IBAction func btnAddCoins(sender: UIButton) {
for product in list {
var prodID = product.productIdentifier
if(prodID == "com.dname.YourApp.addcoins") {
p = product
buyProduct()
break;
}
}
}
*/
/*
// 4
func removeAds() {
lblAd.removeFromSuperview()
}
*/
/*
// 5
func addCoins() {
coins = coins + 50
lblCoinAmount.text = "\(coins)"
}
*/
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func RestorePurchases(sender: UIButton) {
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}
var list = [SKProduct]()
var p = SKProduct()
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)
//println(product.price)
list.append(product )
}
removeAds.enabled = true
//outAddCoins.enabled = true
}
func buyProduct() {
print("buy " + p.productIdentifier)
let pay = SKPayment(product: p)
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment)
}
func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) {
print("transactions restored")
// var purchasedItemIDS = []
for transaction in queue.transactions {
let t: SKPaymentTransaction = transaction
let prodID = t.payment.productIdentifier as String
switch prodID {
case "com.dname.YourApp.removeAds":
//Set the user default to not show ads
userDefaults.setObject(1, forKey: "noAds")
userDefaults.synchronize()
print("remove ads")
//removeAds()
case "com.dname.YourApp.addcoins":
print("add coins to account")
//addCoins()
default:
print("IAP not setup")
}
}
}
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("add paymnet")
for transaction:AnyObject in transactions {
let trans = transaction as! SKPaymentTransaction
print(trans.error)
switch trans.transactionState {
case .Purchased:
print("buy, ok unlock iap here")
print(p.productIdentifier)
let prodID = p.productIdentifier as String
switch prodID {
case "com.dname.YourApp.removeAds":
print("remove ads")
//Set the user default to not show ads
userDefaults.setObject(1, forKey: "noAds")
userDefaults.synchronize()
//removeAds()`enter code here`
case "com.dname.YourApp.addcoins":
print("add coins to account")
//addCoins()
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 trans")
SKPaymentQueue.defaultQueue().finishTransaction(trans)
}
func paymentQueue(queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {
print("Remove Transaction")
}
}