Alex A
Alex A

Reputation: 309

Completion handler not being called - Alamofire / stripe

My completion handler is never called.

This completion handler is written by stripe: (end of step 1) https://stripe.com/docs/mobile/ios/standard#ephemeral-key

Ive tried simplifying the function as much as possible (i made it more complex before), and putting a completion() in the end of every .case .

When i shift click on the STPJSONResponseCompletionBlock it tells me the parameters required are this:

jsonResponse
The JSON response, or nil if an error occured. error
The error that occurred, if any.

if i call completion(nil, nil) i can crash my app, and it gives me this error: 2019-07-30 10:38:42.917984+0100 foodfactory[27595:2238502] *** Assertion failure in -[STPEphemeralKeyManager _createKey],

2019-07-30 10:38:42.929757+0100 foodfactory[27595:2238502] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not parse the ephemeral key response following protocol STPCustomerEphemeralKeyProvider. Make sure your backend is sending the unmodified JSON of the ephemeral key to your app. For more info, see https://stripe.com/docs/mobile/ios/standard#prepare-your-api'

But, if i pass in json as in the example below, it simply never calls..

Furthermore, i have copied the NodeJS code which sent the json to this completion handler as closely as possible (im on google cloud functions so there had to be some changes, and i checked my JSON im receiving and the ephemeral key is there, and i can access it if i write my own method to decode the json).

Also, as i can make it crash, i guess the completion handler must be being called?

This code calls the function with completion handler:

    func changePaymentOptionsButtonTapped() {
        // Setup customer context
        let apiVersion = String(Stripe.version())
        MyAPIClient.sharedClient.createCustomerKey(withAPIVersion: apiVersion) { (ephemeralKeyJson, err) in
            print("ThisIsNeverCalled")
            if let ephemeralKey = ephemeralKeyJson?["id"] as? String {
            } else {
                print("Error parsing JSON from customer creation: See: MyAPIClient - func createCustomerKey")
            }
        }
    }

The function with completion handler:

    func createCustomerKey(withAPIVersion apiVersion: String, completion: @escaping STPJSONResponseCompletionBlock) {
        guard let customerId = KeychainWrapper.standard.string(forKey: Stripe_Customer_Id) else {
            print("Keychain wrapper not retrieving stripe customer Id at MyAPIClient")
//            completion(nil, nil)
            return
        }
        let url = "https://us-central1-foodfactory-813ab.cloudfunctions.net/request_ephemeral_key"
        Alamofire.request(url, method: .post, parameters: [
            "api_version": apiVersion,
            "customerId": customerId,
            ])
            .validate(statusCode: 200..<300)
            .responseJSON { responseJSON in
                switch responseJSON.result {
                case .success(let json):
                    completion(json as? [String: AnyObject], nil)
                case .failure(let error):
                    print("Error creating customer Key (retrieving ephemeral key) with Alamofire. See: MyAPIClient - func createCustomerKey")
                    completion(nil, error)
                }
        }
    }

Anyone got any suggestions? My guess is it's something to do with what im passing into the completion handler.

Upvotes: 0

Views: 703

Answers (1)

mag_zbc
mag_zbc

Reputation: 6992

There's definitely an error here:

json as? [String: AnyObject]

change it to

json as? [String: Any]

The reason for it is that a JSON dictionary can contain things that aren't AnyObject - for instance, String is a struct, Int or Bool aren't objects either

Upvotes: 0

Related Questions