我正在用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,并购买产品按钮的行动。
请帮助我,或者如果一个类似的问题的答案已经存在,给我一个链接到该线程。
发布于 2022-01-08 21:22:24
您的StoreManager类需要符合SKPaymentTransactionObserver --您已经实现了该协议中的相关委托方法,但是您还没有声明一致性,或者,最重要的是,还没有将StoreManager实例添加为事务队列观察者。
由于您没有观察到事务,所以永远不会调用finishTransaction --当您试图第二次购买该消费品时,Store会看到该项目的不完整购买,因此您将得到您已经购买过的消息。
与实际注册为事务队列观察者一样,应用程序在启动时立即创建StoreManager实例也很重要--在didFinishLaunching或同等位置中。
这样,就可以将以前运行的任何不完整的采购显示给事务队列观察者。
您应该只有一个StoreManager实例,它的生存期应该是您的应用程序的生存期。
你需要这样的东西:
class StoreManager : NSObject, ObservableObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
init() {
SKPaymentQueue.default().add(self)
}而且,看到@EnvironmentObject var authViewModel: AuthViewModel会让我觉得您的设计中可能存在一个分离的问题。
发布于 2022-01-07 23:05:16
这是因为有两种类型的应用程序内购买。消耗品和非消耗品。可消费的内购可多次购买,而非-consumable的应用程序内采购只能进行一次。
https://developer.apple.com/in-app-purchase/
解决方案
选中App,连接应用程序中的购买部分,查看您创建的应用程序内购买的类型。如果它是不可消耗的,删除现有的应用程序内购买,并创建一个新的是易耗的。
资源
https://stackoverflow.com/questions/70627760
复制相似问题