2

I have a Cloud Code function that returns several objects, with some of them being Booleans. I would like to do something in my Swift code, based on the boolean values of the returned objects, as seen below. However, I keep getting multiple errors in my implementation.

Cloud Code

Parse.Cloud.define("checkCharge", function(request, response){
    stripe.charges.retrieve(request.params.charge, function(err, charge) {
        if(err){
                console.log(err);
                response.error(err);
        }else{
                console.log("Successfully checked the charge");
                response.success(charge);
        }
}); 
});

Swift Code

PFCloud.callFunctionInBackground("checkCharge", withParameters: ["charge": orderCharge]) { (success: AnyObject?, error: NSError?) -> Void in
//                            if let responseJSON: [String: Bool] = success as? [String: Bool] {
                            if error == nil{
//                                let responseString = response as? String
//                                let chargeCaptured: Bool = success["captured"]
                                let objects = success as! NSArray
                                for object in objects {
                                let chargeCaptured = object["captured"] as! Bool
                                let chargeRefunded: Bool = success["refunded"]
                                let chargePaid: Bool = success["paid"]
                                if chargeCaptured == true || chargeRefunded == true || chargePaid == true{
                                    print("charge already processed charge")
                                    object.deleteInBackground()
                                }else{
                                    self.storyboard
}

I get errors such as ambiguous use of subscript and type AnyObject has no subscript members, whenever I try to set a constant. I also get the error cannot convert type Bool to Bool.

Dups
  • 201
  • 1
  • 2
  • 12
  • Which line of code throws that error. It means that object is of the type AnyObject and doesn't contain the methods you are trying to invoke. You might need to cast it to the desired type. Use if let statements – user1046037 May 29 '17 at 03:07
  • @user1046037 Thank you. I get errors on the lines `let chargeCaptured`, `let chargeRefunded` and `let chargePaid`. – Dups May 29 '17 at 03:34
  • Cast those objects at Bool. Use the `as` operator. Are you familiar with Swift. If yes then please don't force unwrap optionals unless you are 100% sure – user1046037 May 29 '17 at 05:33
  • @user1046037 so this way? ` let objects = success as! NSArray for object in objects { let chargeCaptured = object["captured"] as Bool` – Dups May 29 '17 at 06:05

2 Answers2

1

Problem:

  • After casting into an NSArray you were trying to use it like a dictionary.

Code:

See if this fixes the issues for you:

PFCloud.callFunctionInBackground("checkCharge", withParameters: ["charge": orderCharge]) { data, error in

    //If there is an error, code will not proceed, it will exit
    guard error == nil else {
        print("error = \(error!)")
        return
    }

    //If data is not a dictionary of the type [String : Any] it will exit
    guard let objects = data as? [String : Any] else {
        print("data is not of the type [String : Any]")
        print("actual data type of data = \(type(of: data))")
        return
    }

    if let chargeCaptured   = objects["captured"] as? Bool,
        let chargeRefunded  = objects["refunded"] as? Bool,
        let chargePaid      = objects["paid"] as? Bool,
        chargeCaptured      == true || chargeRefunded == true || chargePaid == true {

        print("charge already processed charge")
        object.deleteInBackground()
    }
    else {

        print("Else condition")
    }
}

Suggestion:

  • Please use Swift native types where ever possible
  • Use guard, if let to conditionally unwrap optionals
  • It would help if you learn the Swift basics.
  • Use Control + I shortcut to format your code in Xcode
user1046037
  • 16,755
  • 12
  • 92
  • 138
  • Thank you. I figured the data was dictionary type. I didn't use your solution as I fixed it before checking stack overflow, but I see that you put one that could work. – Dups May 29 '17 at 07:50
1

It turned out the cloud code returned values as NSDictionary. So this is what I did in Swift.

PFCloud.callFunctionInBackground("checkCharge", withParameters: ["charge": orderCharge]) { (success: AnyObject?, error: NSError?) -> Void in
     if error == nil{
        let objects2 = success as! NSDictionary
        let chargeCaptured = objects2.objectForKey("captured") as! Bool
        let chargeRefunded = objects2.objectForKey("refunded") as! Bool
        let chargePaid = objects2.objectForKey("paid") as! Bool
    }
}
Dups
  • 201
  • 1
  • 2
  • 12
  • Just a note of caution when you use `as!` you are force unwrapping, so if the value is nil the app would crash. Better to use `as?`. – user1046037 May 29 '17 at 11:13
  • @user1046037 I understand, but wouldn't that result in "Optional(true)" for example? – Dups May 29 '17 at 21:47
  • That is correct, it would return an Optional because the value returned from the server might be nil as well. So use an `if let` statement to check if there is a value then you write your code in it. – user1046037 May 30 '17 at 00:33