当我恢复购买时,我需要禁用 View 中的恢复按钮。
我有 IAPManager
类和 SKPaymentTransactionObserver
,它工作正常,我在调用时看到了 SKPaymentTransactionObserver 的 print("restored")
SKPaymentQueue.default().restoreCompletedTransactions
从我的主要观点来看。
那么问题是,从 View 中我没有发现该事件,因此我无法禁用该按钮,因为购买已经恢复。
在我的 IAPManager 中:
func restore(withUsername username: String? = nil) {
SKPaymentQueue.default().add(self)
SKPaymentQueue.default().restoreCompletedTransactions(withApplicationUsername: username)
}
extension IAPManager: SKPaymentTransactionObserver {
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
transactions.forEach {
switch $0.transactionState {
case .purchasing: ()
print("purchasing")
case .deferred: ()
print("deferred")
case .restored: SKPaymentQueue.default().finishTransaction($0)
print("restaured")
UserDefaults.standard.set(true, forKey: "pro")
case .failed: SKPaymentQueue.default().finishTransaction($0)
print("failed")
UserDefaults.standard.set(false, forKey: "pro")
case .purchased: SKPaymentQueue.default().finishTransaction($0)
print("purchased")
UserDefaults.standard.set(true, forKey: "pro")
@unknown default:
break
}
}
}
在我看来:
Text("Available purchases").font(.title3).foregroundColor(.green)
.onTapGesture {
IAPManager.shared.getProducts()
}.padding()
Spacer()
Button(action: {
let purchased = UserDefaults.standard.bool(forKey: "pro")
if !purchased {
print("Going to try restore")
IAPManager.shared.restore()
} else {
print("restored!")
}
}){
Text((buyed ? "Restored" : "Restore" ))
.fontWeight(.bold)
.font(.none)
.padding(6)
.cornerRadius(40)
.foregroundColor(.blue)
.overlay(
RoundedRectangle(cornerRadius: 40)
.stroke(Color.blue, lineWidth: 0.8)
)
}.buttonStyle(PlainButtonStyle())
.disabled( UserDefaults.standard.bool(forKey: "pro"))
.padding()
最佳答案
对于不相关和已经存在的组件之间的通信,您可以使用自定义通知。
- 为您的通知创建一个名称:
extension IAPManager {
static let proNotification = Notification.Name(rawValue: "proNotification")
}
- 在您恢复交易的地方,发送通知,通知所有订阅者 Pro 已恢复:
case .restored:
print("restored")
SKPaymentQueue.default().finishTransaction($0)
NotificationCenter.default.post(name: IAPManager.proNotification, object: nil, userInfo: nil)
- 现在您需要一种方法来观察此通知::
struct ContentView: View {
@State var isPro = false
var body: some View {
Text(isPro ? "pro user" : "standard user")
.onReceive(NotificationCenter.default.publisher(for: IAPManager.proNotification)) { _ in
self.isPro = true
}
}
}
关于ios - SwiftUI View 中的 StoreKit 委托(delegate)/可观察对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63919916/