4

I am working with Flutter and Swift. I'm trying to authorize a credit card using the AuthrizeNet SDK, which unfortunately, does not natively support Flutter. To get around this, I created a Platform Channel in my iOS AppDelegate, which I successfully managed receive data in from Flutter. My question now is how can I return that data from inside the callback handler of the authorizing function (from the AuthorizeNet SDK)? When trying to call the Flutter result function, the Swift compiler throws this error: Escaping closure captures non-escaping parameter 'result'. Here's my code:

handler!.getTokenWithRequest(request, successHandler: { (inResponse:AcceptSDKTokenResponse) -> () in
                let paymentResponseModel: PaymentResponseModel = PaymentResponseModel.init(
                    token: inResponse.getOpaqueData().getDataValue(),
                    resultCode: inResponse.getMessages().getResultCode(),
                    tokenResultDescription: inResponse.getOpaqueData().getDataDescriptor(),
                    messageCode: inResponse.getMessages().getMessages()[0].getCode(),
                    messageText: inResponse.getMessages().getMessages()[0].getText()
                )
                result(String(data: try! JSONEncoder().encode(paymentResponseModel), encoding: String.Encoding.utf8))
            }) { (inError:AcceptSDKErrorResponse) in
                let paymentResponseModel: PaymentModelErrorResponse = PaymentModelErrorResponse.init(
                    code: inError.getMessages().getResultCode(),
                    message: inError.getMessages().getMessages()[0].getCode(),
                    details: inError.getMessages().getMessages()[0].getText()
                )
                result(String(data: try! JSONEncoder().encode(paymentResponseModel), encoding: String.Encoding.utf8))
            }

I've tried different way of calling the result function outside of the getTokenWithRequest function, but I couldn't get it to work. I'm fairly new to Swift programming, so I apologize if this question is vague or has a simple solution. Thank you!

Noah H
  • 93
  • 2
  • 9

1 Answers1

2

The problem is that the successHandler will be called in the future (as a callback), but result must be called immediately and you must return from the method of your code snippet immediately. So, how do you get the success/error response back? You have to make a call from native to Dart when the the token response becomes available. Then, at the Dart end, you'll have to hang about until that response call is made when you can update your app state, and the UI.

It becomes a bi-directional method channel like this:

---token request--->
<---result----------

<---token response--
----result--------->

Neither of the results contains much information, but could be used to convey errors. For example, if the first result comes back false, something went wrong and the Dart end shouldn't expect the token response - it won't happen.

Richard Heap
  • 48,344
  • 9
  • 130
  • 112
  • Thank your for your response! Just to verify I understand your answer, I'll need to send the Method Channel result before the authorizing function, then once it has been authorized, call a Flutter function using another Method Channel (native -> Flutter)? – Noah H Aug 02 '20 at 04:05
  • Correct, except that you can use the same method channel in the opposite direction - no need to create a different one. – Richard Heap Aug 02 '20 at 12:12
  • This however is a feature disparity between Android and iOS. Android side is perfectly capable of returning token-response asynchronously – Zimes Nov 13 '20 at 10:54
  • @Zimes can you please share any example for android side. Can't find any. – Ritesh Singh Jun 13 '22 at 11:17
  • 1
    @RiteshSingh See https://stackoverflow.com/questions/70370222/why-does-methodchannel-result-success-sometimes-cause-a-timeout-at-flutter (ignore the question itself about the timeout and look at the result.success inside the looper lambda. – Richard Heap Jun 13 '22 at 12:52
  • @Zimes thanks that was really helpful. Also found this answer which helped alot https://stackoverflow.com/a/64135497/9231721. – Ritesh Singh Jun 13 '22 at 18:27