Skip to content

Commit

Permalink
Fix PaymentSheet and CustomerSheet in SwiftUI on iOS 18 (#3666)
Browse files Browse the repository at this point in the history
## Summary
- No view controller was being found to present on. To fix we fallback
on the current view controller on the window.
- Fixes for both PaymentSheet and CustomerSheet
- Adds metrics to product usage to track SwiftUI usage.

## Motivation
- Fix PaymentSheet/CustomerSheet <> SwiftUI on iOS 18

## Testing
- Manual on iOS 17.2 and iOS 18

## Changelog
See diff
  • Loading branch information
porter-stripe authored Jun 13, 2024
1 parent f449d8c commit 2dd63df
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
### PaymentSheet
* [Fixed] Fixed an issue where changing the country of a phone number would not update the UI when the phone number's validity changed.
* [Changed] The "save this card" checkbox is now unchecked by default. To change this behavior, set your PaymentSheet.Configuration.savePaymentMethodOptInBehavior to `.requiresOptOut`.
* [Fixed] Fixed an issue where PaymentSheet would not present in the iOS 18 beta when using SwiftUI.

### CustomerSheet
* [Fixed] Fixed an issue where CustomerSheet would not present in the iOS 18 beta when using SwiftUI.

### Payments
* [Added] Updated support for MobilePay bindings.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//
//

@_spi(STP) import StripeCore
import SwiftUI

extension View {
Expand All @@ -16,7 +17,8 @@ extension View {
customerSheet: CustomerSheet,
onCompletion: @escaping (CustomerSheet.CustomerSheetResult) -> Void
) -> some View {
self.modifier(
STPAnalyticsClient.sharedClient.addClass(toProductUsageIfNecessary: SwiftUIProduct.self)
return self.modifier(
CustomerSheet.CustomerSheetPresentationModifier(
isPresented: isPresented,
customerSheet: customerSheet,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// https://github.com/stleamist/BetterSafariView
//

@_spi(STP) import StripeCore
import SwiftUI

extension View {
Expand All @@ -21,7 +22,8 @@ extension View {
paymentSheet: PaymentSheet,
onCompletion: @escaping (PaymentSheetResult) -> Void
) -> some View {
self.modifier(
STPAnalyticsClient.sharedClient.addClass(toProductUsageIfNecessary: SwiftUIProduct.self)
return self.modifier(
PaymentSheet.PaymentSheetPresentationModifier(
isPresented: isPresented,
paymentSheet: paymentSheet,
Expand All @@ -39,7 +41,8 @@ extension View {
paymentSheetFlowController: PaymentSheet.FlowController,
onSheetDismissed: (() -> Void)?
) -> some View {
self.modifier(
STPAnalyticsClient.sharedClient.addClass(toProductUsageIfNecessary: SwiftUIProduct.self)
return self.modifier(
PaymentSheet.PaymentSheetFlowControllerPresentationModifier(
isPresented: isPresented,
paymentSheetFlowController: paymentSheetFlowController,
Expand Down Expand Up @@ -412,6 +415,28 @@ func findViewController(for uiView: UIView) -> UIViewController? {
} else if let nextResponder = uiView.next as? UIView {
return findViewController(for: nextResponder)
} else {
return nil
// Can't find a view, attempt to grab the top most view controller
return topMostViewController()
}
}

func topMostViewController() -> UIViewController? {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let window = windowScene.windows.first(where: { $0.isKeyWindow }) else { return nil }

var topController: UIViewController? = window.rootViewController

// Traverse presented view controllers to find the top most view controller
while let presentedViewController = topController?.presentedViewController {
topController = presentedViewController
}

return topController
}

// Helper class to track SwiftUI usage
final class SwiftUIProduct: STPAnalyticsProtocol {
public static var stp_analyticsIdentifier: String {
return "SwiftUI"
}
}

0 comments on commit 2dd63df

Please sign in to comment.