frames-ios
frames-ios copied to clipboard
Call the completion handler on the main thread
Issue
I don't have access to GitHub issues for this repo, but I have created an official support ticket with reference number 45249 by contacting Checkout's support email.
Proposed changes
This fixes a crash when using the Frames iOS SDK in a SwiftUI app by wrapping the returned UIViewController from PaymentFormFactory.buildViewController(configuration:style:completionHandler:) in a SwiftUI UIViewControllerRepresentable.
Test Steps
I created a small Xcode project to reproduce the issue (Xcode 16.2): FramesCheckoutTestSwiftUI.zip
If you don't have Xcode 16.2 installed try setting the minimum iOS target to 18.0 or 18.1.
You can verify this issue is fixed by tapping the Pay button on the payment form and observing that no crash occurs and the completionHandler is running successfully.
Checklist
- [ ] Reviewers assigned
- [x] I have performed a self-review of my code and manual testing
- [x] Lint and unit tests pass locally with my changes
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] I have added necessary documentation (if applicable)
Further comments
The crash that was occurring on line 185 of DefaultPaymentViewModel was EXC_BREAKPOINT and was occurring on a thread other than the main thread. For some reason this was not an issue when the client integrating this library uses UIKit. This issue only surfaces when attempting to integrate the library on a SwiftUI app. In both cases, I think it's incorrect to complete outside the main thread. So I added the fix.
I also digged a little deeper in the call stack trace and noticed that this issue might be fixed in CheckoutAPIService (by calling completion for CheckoutAPIService.callRiskSDK(tokenDetails:completion:) on the main thread, but since CheckoutAPIService is not directly related or responsible for UI, I think it doesn't need to run on the main thread.
I don't have enough experience with the source code to write a unit test to test for this specific scenario (make sure the completionHandler is always running on the main thread). If you can guide me or add to this pull request yourself, I would appreciate that!