在应用内购买:购买后向用户购买商品

时间:2017-10-02 15:21:28

标签: ios swift in-app-purchase nsuserdefaults

这是一个两部分问题,相互联系,不值得分开问题

第一个问题

所以我刚刚在youtube here上完成了关于应用内购买的指南教程,他主要介绍了购买商品的实际付款和恢复等。

但是他没有说明我实际需要的一件事是实际上给买方(在我的情况下是游戏中的硬币)购买物品的方式

这是包含所有购买功能和其他内容的文件

import Foundation
import StoreKit

class IAPService: NSObject {

    private override init() {}
    static let shared = IAPService()

    var products = [SKProduct]()
    var paymentQueue = SKPaymentQueue.default()

func getProducts() {
    let products: Set = [IAPProduct.StackOfCoins.rawValue,
                         IAPProduct.PileOfCoins.rawValue,
                         IAPProduct.BoxOfCoins.rawValue,
                         IAPProduct.MountainOfCoins.rawValue,
                         IAPProduct.ContainerOfCoins.rawValue]
    let request = SKProductsRequest(productIdentifiers: products)
    request.delegate = self
    request.start()

    paymentQueue.add(self)
}

    func purchase(product: IAPProduct) {
        guard let productToPurchase = products.filter({ $0.productIdentifier == product.rawValue }).first else { return }
        let payment = SKPayment(product: productToPurchase)
        paymentQueue.add(payment)


    }
}
extension IAPService: SKProductsRequestDelegate {
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        self.products = response.products
        print(response.products)
        for product in response.products {
            print(product.localizedDescription)
        }
    }
}
extension IAPService: SKPaymentTransactionObserver {
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            print(transaction.transactionState.status(), transaction.payment.productIdentifier)
            switch transaction.transactionState {
            case .purchasing: break
            default: queue.finishTransaction(transaction)
            }
        }
    }
}
extension SKPaymentTransactionState {
    func status() -> String {
        switch self {
        case .deferred: return "deferred"
        case .failed: return "failed"
        case .purchased: return "purchased"
        case .purchasing: return "purchasing"
        case .restored: return "restored"
        }
    }
}

这是存储我的产品ID的第二个文件

import Foundation
//crappy duck is the name of my game i am developing and these here represent increasing values of coins the user can buy

enum IAPProduct: String {
    case StackOfCoins = "com.HucksCorp.Crappy-duck.StackOfCoins"
    case PileOfCoins = "com.HucksCorp.Crappy-duck.PileOfCoins"
    case BoxOfCoins = "com.HucksCorp.Crappy-duck.BoxOfCoins"
    case MountainOfCoins = "com.HucksCorp.Crappy-duck.MountainOfCoins"
    case ContainerOfCoins = "com.HucksCorp.Crappy-duck.ContainerOfCoins"

}

它工作正常我可以连接和访问我的产品出售(游戏中的硬币)和所有这些,但我无法弄清楚如何更改它,以便它给用户基于项目的游戏币正在购买

这是我用来让用户真正购买东西的东西

这是一个集合视图

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    if indexPath.item == 0 {
        IAPService.shared.pruchase(product: .StackOfCoins)
    }
    if indexPath.item == 1 {
        IAPService.shared.purchase(product: .PileOfCoins)
    }
    if indexPath.item == 2 {
        IAPService.shared.purchase(product: .BoxOfCoins)
    }
    if indexPath.item == 3 {
        IAPService.shared.purchase(product: .MountainOfCoins)
    }
    if indexPath.item == 4 {
        IAPService.shared.purchase(product: .ContainerOfCoins)
    }
}

第二个问题

我将值硬币存储在UserDefaults中,而我之前的一个问题中的其他人警告我,将可购买产品存储在UserDefaults中是个坏主意

UserDefaults的第二个选项是什么,我可以通过应用内购买和游戏内可购买产品访问,添加和减少

摘要

如果我的问题不清楚(如果他们不让我知道,我可以编辑它们)

我的第一个问题是如何在用户购买产品后向用户提供

我的第二个问题是 userDefaults值硬币的另一个选项,它比UserDefaults

更安全

1 个答案:

答案 0 :(得分:2)

updatedTransactions

中添加另一个案例到交换机
switch transaction.transactionState {
    case .purchased:
        let coinsValue = generateValue(transaction.payment.productIdentifier)
        //add a call to your function here
        break;
    case .purchasing: break
    default: queue.finishTransaction(transaction)
}

在这种情况下,根据购买的产品,调用添加硬币的方法。

这是从标识符获取int的方法:

private func generateValue(_ identifier: String) -> Int
{
    switch identifier {
        case "com.HucksCorp.Crappy-duck.StackOfCoins":
            return 1
        case "com.HucksCorp.Crappy-duck.PileOfCoins":
            return 2
        /// etc..
        default:
            return 0
    }
}

关于硬币存储,您可以将它们同步到文件,存储在钥匙串中或使用服务器端存储,这可能是最佳选择。