StoreKit Delegate / Observable object in SwiftUI View

浪尽此生 提交于 2020-12-12 06:28:29

问题


When I restored my purchases, I need to disabled the restore button in the view.

I have IAPManager class with SKPaymentTransactionObserver, and it works fine, I saw the print("restored") of SKPaymentTransactionObserver when I call SKPaymentQueue.default().restoreCompletedTransactions from my principal view.

So, then the problem is that from the view I do not find out about that event and therefore I cannot disable the button, since the purchase has already been restored.

In my 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
        }
    }

}

In my View:

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()

回答1:


For communication between unrelated and already existing components you can use custom Notifications.

  1. Create a name for your Notification:
extension IAPManager {
    static let proNotification = Notification.Name(rawValue: "proNotification")
}
  1. In the place where you restore your transactions, send out the notification informing all subscribers that the Pro is restored:
case .restored: 
    print("restored")
    SKPaymentQueue.default().finishTransaction($0)
    NotificationCenter.default.post(name: IAPManager.proNotification, object: nil, userInfo: nil)
  1. Now you need a way to observe this notification::
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
            }
    }
}


来源:https://stackoverflow.com/questions/63919916/storekit-delegate-observable-object-in-swiftui-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!