3

So, I created a typealias to store a completion handler, to later pass into a function called submitTokenToBackend using Stripe's iOS library. Here is my code:

// MARK: - Create Completion Handlers

typealias CompletionHandler = (_ token: AnyObject?, _ error: NSError?) -> Void

// MARK: - Submit Token To Backend

func submitTokenToBackend(completionHandler: CompletionHandler) {

}

// MARK: - STPPaymentCardTextFieldDelegate


func paymentCardTextFieldDidChange(_ textField: STPPaymentCardTextField) {
    print("Card number: \(textField.cardParams.number) Exp Month: \(textField.cardParams.expMonth) Exp Year: \(textField.cardParams.expYear) CVC: \(textField.cardParams.cvc)")
    self.buyButton.isEnabled = textField.isValid
}

// MARK: Initialize Card Params

let cardParams = STPCardParams()

func cardParamsFunc() {
    cardParams.number = "4242424242424242"
    cardParams.expMonth = 10
    cardParams.expYear = 2018
    cardParams.cvc = "123"
    STPAPIClient.shared().createToken(withCard: cardParams){ (token, error) in

        if let error = error {
            print(error.localizedDescription)

        } else if let token = token {

// HERE'S WHERE I'M GETTING ERRORS

            self.submitTokenToBackend(completionHandler: CompletionHandler) -> Void {
                if let error = error {
            print(error.localizedDescription)
                } else {
                    print("Show receipt page")
            }
        }
    }
}
}

I am getting these weird errors, now, in Swift 3 concerning my completion handler not having expected types. Not an isolated incident, either. Any thoughts?

3 Answers3

1

Almost all thing you need is described in Rob Napier's answer.

I'll try to show you a little more concrete code...

You can define the completion handler and pass it to submitTokenToBackend(completionHandler:) like this:

            let theCompletionHandler: CompletionHandler = {token, error in
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    print("Show receipt page")
                }
            }
            self.submitTokenToBackend(completionHandler: theCompletionHandler)

With removing intermediate let-constant, you can write it in this way:

            self.submitTokenToBackend(completionHandler: {token, error in
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    print("Show receipt page")
                }
            })

Using the trailing closure feature of Swift, the above code can be shortened to:

            self.submitTokenToBackend {token, error in
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    print("Show receipt page")
                }
            }

Your code is far from any of above three.

OOPer
  • 47,149
  • 6
  • 107
  • 142
0

Im not sure, but... Where is 'CompletionHandler' implementation? As I understand, you just declarate some like block in Objective - C ('typedef void (^completionHandler)(id token);'), but don't use it.

Srj0x0
  • 458
  • 3
  • 12
  • @OOper Yep. I was just about to accept Rob Napier's answer. I didn't do anything with the handler and figured it out "on my own" after understanding that I declared the handler without passing anything in. Not sure if I said that correctly, but used a trailing closure and I got it working! Thanks, everyone! –  Aug 21 '16 at 22:52
0
self.submitTokenToBackend(completionHandler: CompletionHandler) -> Void {

This is a declaration, not a method call. You can't pass a typealias as a parameter. And -> Void does not make sense here at all. You almost certainly meant

self.submitTokenToBackend {

If you have further questions on this, however, you need to provide code we can compile (see mcve) and list the exact errors. "Weird errors" is not particularly helpful for debugging.

pkamb
  • 33,281
  • 23
  • 160
  • 191
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Hi Rob. The submitTokenToBackend function with completion handler takes an argument of Completion Handler, the typealias declared earlier **typealias CompletionHandler = (_ token: AnyObject?, _ error: NSError?) -> Void** What am I supposed to pass in if not the Completion Handler? The arguments of the typealias? Wouldn't that defeat the point? –  Aug 21 '16 at 22:25
  • Just doing **self.submitTokenToBackend {** raises the exception **Contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored** with a fix of **_,_ in** which raises the errors **Consecutive statements on a line must be separated by ";"** and **Expected expression** –  Aug 21 '16 at 22:29