【问题标题】:Swift: In-App Purchase consumable can be purchased just onceSwift:应用内购买消耗品只能购买一次
【发布时间】:2022-01-07 22:18:03
【问题描述】:

我正在使用应用内购买在 SwiftUI 中制作应用。在这个应用程序中,用户应该可以购买任意次数的积分,所以我使用了消耗品。但是当我再次尝试购买它们时,我得到了“此应用内购买已被购买。它将免费恢复”的信息。我已经在寻找如何做到这一点的方法,但没有一个想法对我有用。

这是我的 StoreManager 类:

import Foundation
import StoreKit
import SwiftUI

class StoreManager : NSObject, ObservableObject, SKProductsRequestDelegate {
    
    @EnvironmentObject var authViewModel: AuthViewModel
    
    @Published var transactionState: SKPaymentTransactionState?
    @Published var myProducts = [SKProduct]()
    var request: SKProductsRequest!
    
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        print("Did receive response")
        
        if !response.products.isEmpty {
            for fetchedProduct in response.products {
                    DispatchQueue.main.async {
                        self.myProducts.append(fetchedProduct)
                }
            }
            for invalidIdentifier in response.invalidProductIdentifiers {
                print("Invalid identifiers found: \(invalidIdentifier)")
            }
        }else{
            print("it's empty")
        }
    }
    
    func getProducts(productIDs: [String]) {
        let request = SKProductsRequest(productIdentifiers: Set(productIDs))
        request.delegate = self
        request.start()
    }
    
    func request(_ request: SKRequest, didFailWithError error: Error) {
        print("Request did fail: \(error)")
    }
    
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch transaction.transactionState {
            case .purchasing:
                transactionState = .purchasing
                break
            case .purchased:
                print("purchased")
                queue.finishTransaction(transaction)
                transactionState = .purchased
                break
            case .restored:
                print("restored")
                transactionState = .restored
                queue.finishTransaction(transaction)
                break
            case .failed, .deferred:
                    queue.finishTransaction(transaction)
                    transactionState = .failed
                break
                    default:
                    queue.finishTransaction(transaction)
                break
            }
        }
    }
    
    func purchaseProduct(product: SKProduct) {
        
        if SKPaymentQueue.canMakePayments() {
            let payment = SKPayment(product: product)
            SKPaymentQueue.default().add(payment)

        } else {
            print("User can't make payment.")
        }
    }
    
    func restoreProducts() {
        SKPaymentQueue.default().restoreCompletedTransactions()
    }
}

而我只是将 getProducts 与 onAppear 一起使用,并在按钮操作时购买产品。

请帮助我,或者如果已经存在类似问题的答案,请向我发送该主题的链接。

【问题讨论】:

    标签: ios swift xcode in-app-purchase


    【解决方案1】:

    您的 StoreManager 类需要符合 SKPaymentTransactionObserver - 您已经从该协议中实现了相关的委托方法,但您尚未声明符合性,或者最重要的是,将您的 StoreManager 实例添加为事务队列观察者.

    由于您没有观察交易,因此您永远不会致电 finishTransaction - 当您第二次尝试购买该消耗品时,Store Kit 会看到该商品的购买不完整,因此您会收到以下消息:你已经购买了。

    除了实际注册为事务队列观察者外,重要的是您的应用在启动后立即在 didFinishLaunching 或等效位置创建一个 StoreManager 实例。

    这样可以将之前运行的任何未完成购买呈现给您的交易队列观察者。

    您应该只有一个 StoreManager 实例,并且它的生命周期应该是您应用的生命周期。

    你需要这样的东西:

    class StoreManager : NSObject, ObservableObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
        init() {
             SKPaymentQueue.default().add(self)
        }
    

    另外,看到@EnvironmentObject var authViewModel: AuthViewModel 让我认为您的设计中可能存在关注点分离问题。

    【讨论】:

      【解决方案2】:

      这是因为有两种类型的应用内购买。消耗品和 非消耗品。消耗品内购可以多次进行,非消耗品内购只能进行一次。

      https://developer.apple.com/in-app-purchase/

      解决方案

      在 App Store Connect 应用内购买部分查看您创建的应用内购买类型。如果是非消耗品,请删除现有的应用内购买并使用消耗品创建一个新的。

      资源

      Implement In App Purchase (IAP) in iOS applications

      Adding In-App Purchases to a SwiftUI App

      【讨论】:

      • 好的,一切都清楚了,但实际上,每个应用内购买都是消耗品类型。
      猜你喜欢
      • 2021-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多