user1406716
user1406716

Reputation: 9705

How to put asynchronous Parse.com functions in a separate Class in Swift?

I am using Parse.com as my backend. I would like to put all functions/code related to accessing Parse.com in a single class that I can call from different ViewControllers.

Problem is that - since many of these functions from Parse.com are asynchronous, how does one return a value from these functions to update the UI?

For example, in the following function I am going and getting Earnings information of the current user. Since this function is using the asynchronous method findObjectsInBackgroundWithBlock from parse.com, I cannot really return anything from this function.

Is there a workaround to this problem? Currently, I am having to place this in function in the same ViewController class. (and hence having to repeat this same function in multiple viewControllers. Would like to have it in a single function only)

Only solution I see is to go to the synchronous method findObjects. Is there any other way?

func getcurrUserEarnings() {

/// Get details of currentUser from Earnings Class
///
/// :param - NSInterval
/// :returns - Int
func loadEarningsInfo() {

    if (PFUser.currentUser() != nil) {
        var query = PFQuery(className:"Earnings")
        query.whereKey("user", equalTo: PFUser.currentUser()!)
        query.findObjectsInBackgroundWithBlock {
            (objects: [AnyObject]?, error: NSError?) -> Void in

            if error == nil {
                // The find succeeded.
                if let objects = objects as? [PFObject] {
                    for object in objects {
                        println(object.objectId)
                        //WANT TO UPDATE UI HERE WITH THE VALUES THAT WERE JUST RETURNED
                    }
                }
            } else {
                // Log details of the failure
                println("Error: \(error!) \(error!.userInfo!)")
            }
        }
    }
}
}

Upvotes: 0

Views: 183

Answers (1)

Leo
Leo

Reputation: 24714

You can use callback to pass in something.

For example:

func doSomething(callBack:(String)->())->(){
callBack("abc")
}
doSomething { (str:String) -> () in
    println(str)
}

Also, do not forget to update UI on main thread

For example

func loadEarningsInfo(callBack:([PFObject])->()) {

if (PFUser.currentUser() != nil) {
    var query = PFQuery(className:"Earnings")
    query.whereKey("user", equalTo: PFUser.currentUser()!)
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]?, error: NSError?) -> Void in

        if error == nil {
            // The find succeeded.
            if let objects = objects as? [PFObject] {
               callBack(objects)
            }
        } else {
            // Log details of the failure
            println("Error: \(error!) \(error!.userInfo!)")
        }
    }
}
}

Then when you use

loadEarningsInfo { (objects:[PFObject]) -> () in
    //Update UI with objects
}

You can also handle error in callback as well,I just post a simple example

Upvotes: 1

Related Questions