ios – Ready for Delegate Callback in SwiftUI ViewModel then execute code additional

Spread the love


`I am engaged on a Swift/SwiftUI mission the place I am utilizing a UIViewControllerRepresentable to current a STPPaymentHandler for 3D authentication. The 3D authentication course of includes interplay with a delegate that resides within the UIViewControllerRepresentable. After toggling the presentation of the online view, I would like to attend for the delegate callback earlier than continuing with different actions in my SwiftUI ViewModel.

My code in ViewModel:

 {
            self.loadingState = .loading // begin loading
    do {
        /**
         - If person goes to pay from card display screen it will use selectPaymentCar else card can be used
         */
        if  let paymentCard = selectPaymentCard{
            
            let request = strive await walletServices.createSubscription(priceId: self.selectedSubscription!.id, paymentMethod: paymentCard.sort, paymentDetails: ["name": name], paymentMethodId: paymentCard.id)
            
            if request.next_action != nil {
                /// the cardboard requires three d authentication
                self.clientSecret = request.client_secret
                if self.clientSecret != nil { // if consumer secret just isn't nil then present the webview
                    self.present3dView.toggle()
                  
                    
                    if is3dSuccess == "success"{
                        /// if 3d auth is accomplished then verify the subscription
                   
                        let stripeID = retrieveIntent(self.clientSecret!) // get the cost intent id i.e stripe id
                        let isSuccessSubscription = strive await self.confirmSubscription(stripeId: stripeID, card: paymentCard)
                        
                        if isSuccessSubscription {
                            self.subscriptionState = .success
                            self.successMessage = "Subscription Profitable"
                            
                            DispatchQueue.predominant.asyncAfter(deadline: .now() + 0.5){
                                self.loadingState = .loaded
                                self.subscriptionState = .idle
                            }
                        }
                    }else{
                        DispatchQueue.predominant.async {
                            self.subscriptionState = .failed // present Error
                            self.errorMessage = "Fee Failed"
                        }
                    }
                }
            }
            return  await withCheckedContinuation { continuation in
                print(request)
                DispatchQueue.predominant.async {
                    if request.standing == "incomplete"{
                        self.loadingState = .failed // present Error
                        self.errorMessage = "Fee Failed"
                    }else{
                        self.loadingState = .loaded// Finish loading                            
                        self.subscriptionState = .success
                    }
                }
                
                continuation.resume(returning: request.standing ?? "")
                
            }
        }else{
            guard let card = card else {
                return ""
                self.loadingState = .failed
            }
            let request = strive await walletServices.createSubscription(priceId: self.selectedSubscription!.id, paymentMethod: card.paymentMethodType, paymentDetails: ["name": name], paymentMethodId: card.paymentId)
            return  await withCheckedContinuation { continuation in
                Job{
                    if savingNewCard {
                        //Name verify Fee
                        /**
                         - API Response modified so commenting out under code
                         */
                        //strive await confirmPayment(request.clientSecret, paymentMethodId: card.paymentId)
                    }
                }
               
                continuation.resume(returning: request.standing ?? "")
                
            }
        }

   
        
    }catch let error {
        
        print("ERROR PROCESSING SUBSCRIPTION (error.localizedDescription)")
    }
    self.loadingState = .failed
    return ""
}`

after this self.present3dView.toggle() I would like watch for name again of the delegate after which execute remainder of the code

My UIViewRepresentable code:

 `class Coordinator: NSObject,STPAuthenticationContext,     PaymentHandlerDelegate {
    
    
   
    
    var guardian: PaymentHandlerView
   
    
    init(_ guardian: PaymentHandlerView) {
           self.guardian = guardian
           tremendous.init()
           guardian.VC.delegate = self  // Set the delegate
       }
    
    func didFinishPaymentAuthentication(_ success: Bool, worth: String) {
        guardian.isSuccess.wrappedValue = success
        guardian.successMessage.wrappedValue = worth
    }
   
    
    func authenticationPresentingViewController() ->     UIViewController {
        return guardian.VC
    }        

}`

My View controller code for STPHandler:

`

#if !EXTENSION

   func handleAuthenticationStatus(_ clientSecret: String) async  throws {

       let response =  strive await STPPaymentHandler.sharedHandler.confirmSetupIntent(STPSetupIntentConfirmParams(clientSecret: clientSecret), with: self) {[weak self] nextAction, _, error in
            change nextAction {
            case .succeeded:
                ///Dismiss the View
                print("Succeeded")
                self?.delegate?.didFinishPaymentAuthentication(true,worth: "success")
            case .canceled:
                print("canceld")
                self?.delegate?.didFinishPaymentAuthentication(false, worth: "cancelled")
            case .failed:
                print("failed")
                self?.delegate?.didFinishPaymentAuthentication(false, worth: "failed")
            }
        }
    }
    #endif`

and I’m utilizing a swiftUI View as bridge between UIViewRepresentable and ViewModel:

`

  struct PaymentWebView: View {


 @EnvironmentObject var viewModel: PaymentViewModel
 // let url: URL
let clientSecret: String
@State var isSuccess: Bool = false

var physique: some View {
    PaymentHandlerView(clientSecret: clientSecret, isSuccess: $isSuccess, successMessage: $viewModel.is3dSuccess)
        .onChange(of: isSuccess) { newValue in
            if newValue {
                //Dismiss the view
                viewModel.present3dView = false
            }
        }
}
}
 `

After toggle I wish to watch for the delegate name again after which execute remainder of my code for that perform I’m not positive obtain this. This line if is3dSuccess == “success” ought to solely be executed after my delegate name again.

I attempted utilizing some time loop till success message is change however that block the UI and will not let my ViewController load absolutely.

Leave a Reply

Your email address will not be published. Required fields are marked *