`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.