Reputation: 1835
I'm looking to run a Cloud-Code function from a Swift application and receive an object as a response. The response object from Parse is a standard JSON object as defined below and is not an object stored is Parse. Essentially, I'm looking to end up with an custom object defining the results of a cloud function's execution, not an object stored in the database.
I'm struggling with decoding the CloudCode response on the Swift side of things to a custom object following the Decodable
protocol.
Parse.Cloud.define("MyCloudFunc", function(request, response) {
var results = {
"someBooleanProperty": true,
"someIntProperty": 1,
};
response.success(results);
}
PFCloud.callFunction(inBackground: "MyCloudFunc", withParameters: []) { (result, error) in
// Printing `result` at this point shows what appears to be a JSON object.
guard let data = result as? Data else { return }
// Whatever type `result` actually is cannot be cast as Data, so we never make it past here.
guard let response = try? JSONDecoder().decode(MyDecodableStruct, from: data) else { return }
// DO SOMETHING WITH THE RESULT
}
struct MyDecodableStruct: Decodable {
var someBooleanProperty:Bool
var someIntProperty: Int
}
How can I take that response from the Parse Cloud Code and end up with a decoded object of type MyDecodableStruct
?
As suggested in the comments/answers, Parse is returning a Dictionary. I have been able to get everything working with the below; however, I feel there is a better way than double-conversion.
PFCloud.callFunction(inBackground: "MyCloudFunc", withParameters: []) { (result, error) in
guard let jsonString = result as? String else { return }
guard let data = jsonString.data(using: String.Encoding.utf8) else { return }
guard let response = try? JSONDecoder().decode(MyDecodableStruct.self, from: data) else { return }
// DO SOMETHING WITH RESULT.
}
Am I overlooking a way to convert from the Dictionary
directly Data
without doing the JSON conversion in-between?
Upvotes: 0
Views: 724
Reputation: 62676
Part of PFCloud
's job is to create generic collection types from the cloud function response. Since the cloud function is answering a JS object, PFCloud
should -- without the app noticing -- transmit JSON and parse it before invoking the callFunction
callback.
So the posted cloud code result will the be a dictionary. Check to see that with...
if result is Dictionary<AnyHashable,Any> {
print("result is a Dictionary")
}
To convert that to the OP struct, add a from-dictionary initializer to it...
struct MyDecodableStruct: Decodable {
var someBooleanProperty:Bool
var someIntProperty: Int
init(dictionary: [AnyHashable,Any]) {
self.someBooleanProperty = dictionary["someBooleanProperty"] as? Bool ?? false
self.someIntProperty = dictionary["someIntProperty"] as? Int ?? 0
}
}
Upvotes: 3