恢复应用内购买时出现 StoreKit 问题
StoreKit problem while restoring In-App Purchase
我试图找到有关 IAP 的教程,我发现:This one
但是当我调用恢复函数时,没有任何反应。我调用的 OnTap 按钮:store.restorePurchase()
extension Store {
func product(for identifier: String) -> SKProduct? { ...}
func purchaseProduct (_ product: SKProduct){ ...}
func restorePurchases() {
SKPaymentQueue.default().restoreCompletedTransactions()
print("restore")
}
}
restore 打印在我的控制台中。这是控制台中唯一打印的内容。但是在上面的代码中,你可以看到.restored:that should print "UserIsPremium"
extension Store : SKPaymentTransactionObserver {
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions : [SKPaymentTransaction]){
for transaction in transactions {
var shouldFinishTransaction = false
switch transaction.transactionState{
case .purchased, .restored:
completedPurchases.append(transaction.payment.productIdentifier)
print("UserIsPremium")
shouldFinishTransaction = true
case .failed:
print("NotPremium")
shouldFinishTransaction = true
case .deferred, .purchasing:
print("...")
break
@unknown default:
print("unknown")
break
}
if shouldFinishTransaction {
print("shouldfinish")
SKPaymentQueue.default().finishTransaction(transaction)
DispatchQueue.main.async {
self.purchaseCompletionHandler?(transaction)
self.purchaseCompletionHandler = nil
}
}
}
}
}
我的 class 商店:
import StoreKit
typealias FetchCompletionHandler = (([SKProduct]) -> Void)
typealias PurchaseCompletionHandler = ((SKPaymentTransaction?) -> Void)
class Store: NSObject, ObservableObject {
@Published var allFullVersion = [FullVersion]()
private let allProductsIdentifiers = Set ([
"ClemPapplis.OrientationEPS.versionFull"
])
private var completedPurchases = [String]() {
didSet {
DispatchQueue.main.async{ [weak self] in
guard let self = self else { return }
for index in self.allFullVersion.indices {
if self.completedPurchases.contains(self.allFullVersion[index].id){
print("completedPurchases")
UserDefaults.standard.setValue(true, forKey: "Premium")
}
self.allFullVersion[index].isLocked =
!self.completedPurchases.contains(self.allFullVersion[index].id)
}
}
}
}
我使用沙盒测试器。
如果我购买商品,没问题,数据会打印在控制台中。
我是不是忘记了什么?
我已经有几年没有使用 StoreKit 了,但我记得我也有一个关于恢复购买的问题(是的,@ElTomato 是正确的,使用一个单独的案例 - 我很惊讶你的代码实际上构建了)。我发现以下方法有效:
public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction:AnyObject in transactions {
if let trans = transaction as? SKPaymentTransaction {
switch trans.transactionState {
case .purchased:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
delegate.purchaseComplete()
case .failed:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
case .restored:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
default:
break
}}}
}
func restorePurchases() {
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()
}
public func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
for _ in queue.transactions {
alreadyPurchased = true
delegate.purchasesRestored()
}
showAlert("Purchases have been restored.")
}
不用担心 showAlert
,那只是我对 UIViewController
的扩展。但是我在您的代码中没有看到的是 paymentQueueRestoreCompletedTransactionsFinished(_ queue:)
.
我遵循了相同的教程我认为你没有 select select none 在这里
configuration
要在您的模拟器中恢复,您应该 select none 当您 select none 它会尝试在应用程序购买配置中连接苹果开发者。试试看,让我知道。
我试图找到有关 IAP 的教程,我发现:This one
但是当我调用恢复函数时,没有任何反应。我调用的 OnTap 按钮:store.restorePurchase()
extension Store {
func product(for identifier: String) -> SKProduct? { ...}
func purchaseProduct (_ product: SKProduct){ ...}
func restorePurchases() {
SKPaymentQueue.default().restoreCompletedTransactions()
print("restore")
}
}
restore 打印在我的控制台中。这是控制台中唯一打印的内容。但是在上面的代码中,你可以看到.restored:that should print "UserIsPremium"
extension Store : SKPaymentTransactionObserver {
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions : [SKPaymentTransaction]){
for transaction in transactions {
var shouldFinishTransaction = false
switch transaction.transactionState{
case .purchased, .restored:
completedPurchases.append(transaction.payment.productIdentifier)
print("UserIsPremium")
shouldFinishTransaction = true
case .failed:
print("NotPremium")
shouldFinishTransaction = true
case .deferred, .purchasing:
print("...")
break
@unknown default:
print("unknown")
break
}
if shouldFinishTransaction {
print("shouldfinish")
SKPaymentQueue.default().finishTransaction(transaction)
DispatchQueue.main.async {
self.purchaseCompletionHandler?(transaction)
self.purchaseCompletionHandler = nil
}
}
}
}
}
我的 class 商店:
import StoreKit
typealias FetchCompletionHandler = (([SKProduct]) -> Void)
typealias PurchaseCompletionHandler = ((SKPaymentTransaction?) -> Void)
class Store: NSObject, ObservableObject {
@Published var allFullVersion = [FullVersion]()
private let allProductsIdentifiers = Set ([
"ClemPapplis.OrientationEPS.versionFull"
])
private var completedPurchases = [String]() {
didSet {
DispatchQueue.main.async{ [weak self] in
guard let self = self else { return }
for index in self.allFullVersion.indices {
if self.completedPurchases.contains(self.allFullVersion[index].id){
print("completedPurchases")
UserDefaults.standard.setValue(true, forKey: "Premium")
}
self.allFullVersion[index].isLocked =
!self.completedPurchases.contains(self.allFullVersion[index].id)
}
}
}
}
我使用沙盒测试器。 如果我购买商品,没问题,数据会打印在控制台中。
我是不是忘记了什么?
我已经有几年没有使用 StoreKit 了,但我记得我也有一个关于恢复购买的问题(是的,@ElTomato 是正确的,使用一个单独的案例 - 我很惊讶你的代码实际上构建了)。我发现以下方法有效:
public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction:AnyObject in transactions {
if let trans = transaction as? SKPaymentTransaction {
switch trans.transactionState {
case .purchased:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
delegate.purchaseComplete()
case .failed:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
case .restored:
SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
default:
break
}}}
}
func restorePurchases() {
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions()
}
public func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
for _ in queue.transactions {
alreadyPurchased = true
delegate.purchasesRestored()
}
showAlert("Purchases have been restored.")
}
不用担心 showAlert
,那只是我对 UIViewController
的扩展。但是我在您的代码中没有看到的是 paymentQueueRestoreCompletedTransactionsFinished(_ queue:)
.
我遵循了相同的教程我认为你没有 select select none 在这里
configuration
要在您的模拟器中恢复,您应该 select none 当您 select none 它会尝试在应用程序购买配置中连接苹果开发者。试试看,让我知道。