Closed russellyeo closed 1 year ago
Hi @rus64, thanks for filing this!
This is a strange error, and I'm unable to reproduce it locally in a test SPM app. It looks like the compiler might be stripping out our extensions. Can you share your custom build settings? Are you using iXGuard or any other third-party post-processing tools?
I've prepared a fix that might help: Could you point SPM to the davidme/remove-nsdictionary-tech-debt
branch and let me know if you still see the issue?
Thanks!
Hey @davidme-stripe, thanks for looking into this and getting back to me.
As far as I know we are not using any post-processing tools like iXGuard or similar.
Good news, I tried resolving the library from that branch via SPM and the crash goes away! Looks like your fix solved the issue, nicely done.
Hoping you can include it in the next release?
Thank you
Great, thanks for the confirmation! We'll land this fix in v23.1.1, which should go out early next week.
v23.1.1 is out. Let us know if you're still seeing any other crashes or linker issues.
Hey @davidme-stripe, thanks for the update. I've pulled 23.1.1 and tested the integration. I can confirm that the card payments as described above are going through as expected, but unfortunately, I've found another crash when attempting to pay with Apple Pay:
libc++abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[StripeCore.STPAPIClient createPaymentMethodWithPayment:completion:]: unrecognized selector sent to instance 0x60000204fde0'
terminating with uncaught exception of type NSException
The code calling it:
import StripeCore
import StripePayments
extension STPAPIClient: StripeAPIClient {
public func createApplePayPaymentMethod(
for payment: PKPayment,
completion: @escaping (Result<DepopPaymentsPaymentMethod, StripeError>) -> Void
) {
createPaymentMethod(with: payment) { (paymentMethod, error) in
if let paymentMethod = paymentMethod {
completion(.success(paymentMethod))
} else if let error = error {
completion(.failure(.sdkError(error)))
} else {
completion(.failure(.unknown))
}
}
}
}
Hi @rus64, thanks for following up. It does sound like the linker could be stripping out our extensions. I'll dig into Clang's settings and try to reproduce this.
One suggestion: Does adding Never mind, I just realized you're integrating Apple Pay manually.import StripeApplePay
(and adding the StripeApplePay library via SPM) resolve the issue?
@rus64, I'm still unable to reproduce this with all the Clang flags I can find related to Objective-C, symbol stripping, and link-time optimization. Sorry for the continued inconvenience! A few more questions:
-ObjC
flag to your framework/app's "Other Linker Flags" in Xcode?-ObjC -all_load
. (This will increase the binary size, so it shouldn't be enabled when shipping the app.)Hey @davidme-stripe, thanks for the continued support on this, it's very much appreciated.
-ObjC
here. -ObjC -all_load
as well with no success.Thanks
Closing this issue as it is now resolved. After further correspondence with @davidme-stripe via email, he helped me to find the root cause and fix the issue (thanks David!).
We are using Tuist to generate Xcode project files for our application, and with this set up it is necessary to pass the "-Objc" flag in the main application target AND any intermediate targets between this and the Stripe library. Without this, the linker will strip Objective-C category methods, leading to the exception described in this issue.
Relevant links
Summary
An NSInvalidArgumentException crash occurs after attempting to call createPaymentMethod(with:completion:) using the
paymentMethodParams
extracted from aSTPPaymentCardTextField
.The stack trace shows this line as being the last line to be executed. It appears the
stp_dictionaryByRemovingNulls()
method cannot be accessed.I can also see, using a proxy application, that a request is successfully made to
POST https://api.stripe.com/v1/payment_methods
:Request
Response
It appears the issue happens when attempting to decode the response.
Code to reproduce
(Simplified for the purpose of explanation)
iOS version
iPhone 14 Pro Simulator (iOS 16.0)
Installation method
SPM
SDK version
23.1.0
Other information
In our application, it is a requirement that we create a Payment Method first before using the ID to confirm the payment, rather than passing in the
STPPaymentMethodParams
to aSTPPaymentIntentParams
object and confirming the payment in one go.