首页 > 解决方案 > SwiftUI - 不清楚如何使用异步方法处理警报

问题描述

如果用户点击它,我必须在视图上显示警报。

我的警报取决于几种情况:

  1. 商品已购买。显示项目。
  2. 物品尚未购买。显示一个提醒,告诉用户必须购买该物品。此警报必须显示两个按钮,确定购买,取消取消。
  3. 用户点击购买商品。
  4. 购买成功,出示商品。
  5. 购买失败,显示错误。

我就是这样做的。

  class AlertDialog {
    enum SelectedType {
      case none
      case purchase
      case mustBePurchased
      case purchaseError
    }
    
    var selectedType:SelectedType = .none

  }


struct FilteredListItem: View {

  @State var showAlert: Bool = false
  private var alertDialog:AlertDialog?

 var body: some View {
      Text(item.termLowerCase)
        .font(fontItems)
        .foregroundColor(.white)
        .onTapGesture {
          DispatchQueue.main.async {            
            appStoreWrapper.verifyPurchase(productID: item.package!)
            { // run if purchased
              purchased = true
            } runIfNotPurchased: {
              purchased = false
              alertDialog!.selectedType = .mustBePurchased
              showAlert = true
            } 
          }
        }
    .alert(isPresented: $showAlert) {       
      if alertDialog!.selectedType  == .purchase {
        appStoreWrapper.purchase(productID: item.package!) {
          // run if purchased
          purchased = true
        } runIfPurchaseFailed: { (error) in
          alertDialog!.selectedType = .purchaseError
          appStoreWrapper.purchaseError = error
          showAlert = true
        }
        
      } else if alertDialog!.selectedType  == .purchaseError {
        let primaryButton = Alert.Button.default(Text("OK")) {
          showAlert = false
        }
        return Alert(title: Text(appStoreWrapper.makeString("ERROR")),
                     message: Text(appStoreWrapper.purchaseError),
                     dismissButton: primaryButton)
        
      }
    
      
      let dismissButton = Alert.Button.default(Text(appStoreWrapper.makeString("CANCEL"))) {
        showAlert = false
      }
      
      let primaryButton = Alert.Button.default(Text("OK")) {
        appStoreWrapper.purchase(productID: item.package!) {
          // run if purchased
          purchased = true
        } runIfPurchaseFailed: { (error) in
          appStoreWrapper.purchaseError = error
          alertDialog!.selectedType = .purchaseError
          showAlert = true
          print(erro)
        }
      }
      
      return Alert(title: Text(appStoreWrapper.makeString("ERROR")),
                   message: Text(appStoreWrapper.purchaseError),
                   primaryButton: primaryButton,
                   secondaryButton: dismissButton)
    }

这是我的问题:修饰符.alert(isPresented: $showAlert)期望Alert()返回一个,对吗?但我有这些异步方法

appStoreWrapper.verifyPurchase(productID: item.package!)
        { // run if purchased }, 
        runIfNotPurchased: { }

不能将任何内容返回给警报修饰符。我怎么做?我做的对吗?

标签: swiftswiftui

解决方案


您的代码中有很多内容,您没有发布 appStoreWrapper 的代码,但这里有一些代码应该能够为您指明正确的方向。

供参考:

  • 您可以将 Button 与 Action 一起使用,而不是将 Text 与 .onTapGesture 一起使用

  • .Alert 中的代码只能用于获取警报。您不应该在 .Alert 闭包中执行其他操作。

     struct FilteredListItem: View {
    
         @State var showAlert: Bool = false
         private var alertDialog: AlertDialog?
    
         var body: some View {
             Button(action: {
                 verifyItem()
             }, label: {
                 Text("ITEM NAME")
                     .foregroundColor(.white)
             })
             .accentColor(.primary)
             .alert(isPresented: $showAlert, content: {
                 getAlert()
             })
         }
    
         func verifyItem() {
             // FUNCTION TO VERIFY ITEM HERE
             var success = true //appStoreWrapper.verifyPurchase...
    
             if success {
                 // Handle success
             } else {
                 alertDialog?.selectedType = .mustBePurchased
                 showAlert.toggle()
             }
         }
    
         func purchaseItem() {
             // FUNCTION TO PURCHASE ITEM HERE
             var success = true //appStoreWrapper.purchase...
    
             if success {
                 // Handle success
             } else {
                 alertDialog?.selectedType = .purchaseError
                 showAlert.toggle()
             }
         }
    
         func getAlert() -> Alert {
             guard let dialog = alertDialog else {
                 return Alert(title: Text("Error getting alert dialog."))
             }
    
             switch dialog.selectedType {
             case .purchaseError:
                 return Alert(
                     title: Text("Error purchasing item."),
                     message: nil,
                     dismissButton: .default(Text("OK")))
             case .mustBePurchased:
                 return Alert(
                     title: Text("Items have to be purchased."),
                     message: nil,
                     primaryButton: .default(Text("Purchase"), action: {
                         purchaseItem()
                     }),
                     secondaryButton: .cancel())
             case .none, .purchase:
                 return Alert(title: Text("Purchased!"))
             }
         }
    
     }
    

推荐阅读