5

I'm going to try to explain this as best as I can.

I am using Parse.com and returning data from a Parse database class. I want to put this parse.com call in its own function in a custom class. The problem I am having is the completion. Where does it go? I've tried many different versions of adding it to my function but it isn't working.

Here is the function that takes the class name, table name, and sort descriptor and returns an array:

func queryDataInBackgroundWithBlock(parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor) -> [Any]

When I add the completion to it I use (which may not be correct):

func queryDataInBackgroundWithBlock(parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor, completion: (result: Any)->Void)

Now inside the function I use the Parse.com code to go out and get the data

    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]!, error: NSError!) -> Void in
        if error == nil {

            // Do something with the found objects
            for object in objects {
                self.arrayOfObjects.append(object[parseObject]!)
            }

        } else {
            // Log details of the failure
            println("Error: \(error) \(error.userInfo!)")
        }

    }

My goal here is to send parameters to my class function, get the data from parse.com and then return the data as an Array AFTER the async call

I am trying to call it like this:

myClass.queryDataInBackgroundWithBlock("databaseName", parseObject: "columnName", sortDescriptor: orderBy){
    (result: Any) in
    println(result)
}

It's almost like it is a nested completion. How do I return the array after it is completed? Is it handed off to the function which then returns it, or does it need to return in the nested code, or what? It retrieves the data but the problem is the return AFTER completion.

UPDATE: As I stated in the comment below:

query.findObjectsInBackgroundWithBlock({
    (objects: [AnyObject]!, error: NSError!) -> Void in
    if error == nil {

        // Do something with the found objects
        for object in objects {
            self.arrayOfObjects.append(object[parseObject]!)
        }

    } else {
        // Log details of the failure
        println("Error: \(error) \(error.userInfo!)")
    }

}, completion: {
     //do something here
})

This is returning the error: "Extra argument completion in call" I'm not sure how to add the completion at the end of the block so I added () around the block and inserted the completion. This is obviously wrong but I'm not sure how to add the completion at the end of the block as matt has suggested

UPDATE 2:

    func queryDataInBackgroundWithBlock(parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor) -> [Any]{
        var query = PFQuery(className:parseClass)

        if sortDescriptor.key != "" {
            query.orderBySortDescriptor(sortDescriptor)
        }

        query.findObjectsInBackgroundWithBlock {
            (objects: [AnyObject]!, error: NSError!) -> Void in
            if error == nil {

                // Do something with the found objects
                for object in objects {
                    self.arrayOfObjects.append(object[parseObject]!!)
                }

            } else {
                // Log details of the failure
                println("Error: \(error) \(error.userInfo!)")
            }

        }

        return self.arrayOfObjects  //<-- needs to move to completion
    }
2
  • Please copy and paste, in full, into the question, your entire implementation of func queryDataInBackgroundWithBlock(parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor, completion: (result: Any)->Void). Commented Dec 16, 2014 at 21:13
  • updated answer - you will see that I am simply doing what I have consistently been saying you should do... Commented Dec 16, 2014 at 22:48

1 Answer 1

6

Inside the function queryDataInBackgroundWithBlock you receive the completion block under the name completion. It takes one parameter. So the last thing you do, after you have the data, is call it, handing it the data:

completion(result:myData)

And since query.findObjectsInBackgroundWithBlock is itself async, you will need to make that call as the last thing inside the block of query.findObjectsInBackgroundWithBlock.

Like this:

func queryDataInBackgroundWithBlock(
    parseClass:String, parseObject:String, sortDescriptor:NSSortDescriptor, 
    completion: (result: Any)->Void) 
{
    var query = PFQuery(className:parseClass)

    if sortDescriptor.key != "" {
        query.orderBySortDescriptor(sortDescriptor)
    }

    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]!, error: NSError!) -> Void in
        if error == nil {

            // Do something with the found objects
            for object in objects {
                self.arrayOfObjects.append(object[parseObject]!!)
            }

        } else {
            // Log details of the failure
            println("Error: \(error) \(error.userInfo!)")
        }
        completion(result:self.arrayOfObjects)
    }

}
Sign up to request clarification or add additional context in comments.

11 Comments

I actually don't need to pass a parameter to the completion so should it say completion:()->[Any]. And that findIbjectsInBackground is a parse.com function. I think you're telling me to put the completion in there but I'm not sure how to do that
Yes you do have to pass a parameter (actually it's an argument). You yourself have declared completion as having the type (result: Any)->Void. You must supply a result argument when you call completion(...).
Look at the code you cited above. You are calling query.findObjectsInBackgroundWithBlock with a block. That block is your code. I'm saying put the call to completion(...) in there, at the end, to signify that the block is done.
I've tried 20 different ways to do this and get an error every time. What seems like it SHOULD work is query.findObjectsInBackgroundWithBlock({ BLOCK CODE }, completion: { ... }) but I get the error Extra argument completion in call which is telling me that I'm sending a completion argument to findObjectsInBackgroundWithBlack which is part of the PFQuery class written by parse.com. If I try without the () then the error is Consecutive statements on a line must be separated by ;
Well, that would be another question. You're making some kind of basic Swift syntax error. But that has nothing to do with the question you asked. You asked how to do this and, based on the info you provided, I tried to help you. I don't know what your error-generating code looks like so how can I help you with it? If you are getting syntax errors, then try to implement what I said to implement and ask a new question (or even edit the current question) showing your actual code and the actual error you're getting. I can't help you correct your code unless I can see the code to correct.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.