如何使用 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")
}

}