Reputation: 309
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
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