簡體   English   中英

Swift:應用內購買消耗品只能購買一次

[英]Swift: In-App Purchase consumable can be purchased just once

我正在使用應用內購買在 SwiftUI 中制作應用。 在這個應用程序中,用戶應該可以購買任意次數的積分,所以我使用了消耗品。 但是當我再次嘗試購買它們時,我得到了“此應用內購買已被購買。它將免費恢復”的信息。 我已經在尋找如何做到這一點的方法,但沒有一個想法對我有用。

這是我的 StoreManager class:

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 一起使用,並在按鈕操作時購買產品。

請幫助我,或者如果已經存在類似問題的答案,請向我發送指向該主題的鏈接。

這是因為有兩種類型的應用內購買。 消耗品和非消耗品。 消耗性內購可以多次進行,非消耗性應用內購買只能進行一次。

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

解決方案

在 App Store Connect 應用內購買部分查看您創建的應用內購買類型。 如果是非消耗品,請刪除現有的應用內購買並創建一個新的消耗品。

資源

在 iOS 應用程序中實施應用內購買 (IAP)

將應用內購買添加到 SwiftUI 應用

您的StoreManager class 需要符合SKPaymentTransactionObserver - 您已經實現了該協議的相關委托方法,但您尚未聲明符合性,或者最重要的是,將您的StoreManager實例添加為事務隊列觀察者。

由於您沒有觀察交易,因此您永遠不會調用finishTransaction - 當您第二次嘗試購買消耗品時,Store Kit 會看到該物品的購買不完整,因此您會收到已購買的消息.

除了實際注冊為事務隊列觀察者之外,您的應用程序在啟動后立即創建StoreManager實例也很重要 - 在didFinishLaunching或等效位置。

這樣可以將之前運行的任何未完成購買呈現給您的交易隊列觀察者。

您應該只擁有一個StoreManager實例,並且它的生命周期應該是您的應用程序的生命周期。

你需要類似的東西:

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

此外,看到@EnvironmentObject var authViewModel: AuthViewModel讓我認為您的設計中可能存在關注點分離問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM