peterk
peterk

Reputation: 329

How to present the STPPaymentOptionsViewController in swift ui

.sheet(isPresented: $showSheet) {
    STPPaymentOptionsViewController()
} 

I run this code hoping to present the Stripe Payment Options View Controller in my content view and I get this error:

Instance method sheet(isPresented:onDismiss:content:) requires that STPAddCardViewController conform to View

I also tried to wrap the view into a UIViewRepresentable like so:

struct PaymentOptionsView: UIViewRepresentable {
    func makeUIView(context: Context) -> STPPaymentOptionsViewController {
        let config = STPPaymentConfiguration()
        config.additionalPaymentOptions = .default
        config.requiredBillingAddressFields = .none
        config.appleMerchantIdentifier = "dummy-merchant-id"
        return STPPaymentOptionsViewController(configuration: config, e: STPTheme(), customerContext: STPCustomerContext(), delegate: self as! STPPaymentOptionsViewControllerDelegate)   
    }
}

Then I get the error:

Type CheckOut.PaymentOptionsView does not conform to protocol UIViewRepresentable.

Upvotes: 2

Views: 1747

Answers (1)

gotnull
gotnull

Reputation: 27214

Considering that STPPaymentOptionsViewController inherits from ViewController you need to use UIViewControllerRepresentable instead.

You also need to implement the required delegate methods for the STPPaymentOptionsViewControllerDelegate.

struct PaymentOptionsView: UIViewControllerRepresentable {
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, STPPaymentOptionsViewControllerDelegate {
        var control: PaymentOptionsView

        init(_ control: PaymentOptionsView) {
            self.control = control
        }

        // Implement required delegate methods here:
        func paymentOptionsViewControllerDidCancel(_ paymentOptionsViewController: STPPaymentOptionsViewController) {

        }

        func paymentOptionsViewControllerDidFinish(_ paymentOptionsViewController: STPPaymentOptionsViewController) {

        }

        func paymentOptionsViewController(_ paymentOptionsViewController: STPPaymentOptionsViewController, didFailToLoadWithError error: Error) {

        }
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<PaymentOptionsView>) -> STPPaymentOptionsViewController {
        let config = STPPaymentConfiguration()
        config.additionalPaymentOptions = .default
        config.requiredBillingAddressFields = .none
        config.appleMerchantIdentifier = "dummy-merchant-id"

        return STPPaymentOptionsViewController(configuration: config, theme: STPTheme(), apiAdapter: STPCustomerContext(), delegate: context.coordinator)
    }

    func updateUIViewController(_ uiViewController: STPPaymentOptionsViewController, context: UIViewControllerRepresentableContext<PaymentOptionsView>) { }
}

Keep in mind you're also setting the delegate in the STPPaymentOptionsViewController incorrectly. You need to use context.coordinator rather than self as! STPPaymentOptionsViewControllerDelegate.

Upvotes: 2

Related Questions