简体   繁体   中英

Return JSON data from Parse Cloud Code to a Decodable Struct in Swift

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.

Sample Cloud Code

Parse.Cloud.define("MyCloudFunc", function(request, response) {
    var results = { 
        "someBooleanProperty": true, 
        "someIntProperty": 1,
    };
    response.success(results);
}

Sample Swift Code

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
}

Decodable Struct

struct MyDecodableStruct: Decodable {
    var someBooleanProperty:Bool
    var someIntProperty: Int
}

Question

How can I take that response from the Parse Cloud Code and end up with a decoded object of type MyDecodableStruct ?

UPDATE

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?

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
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM