Search code examples
swiftfunctionparse-platformpfquerypfquerytableviewcontrolle

How do I call a function only if another function is complete? (Swift and retrieving from Parse)


I am trying to only call a function only if I have retrieved a certain PFObjectfrom my Parse backend in a separate function. At the moment I am calling this second function after a set delay of 3.0 and it is working, but only if the first query function is called within 3.0, otherwise I have to pullToRefresh the tableView after the first function is eventually finished for it to populate with the Parse data. (I am using a PFQueryTableViewController by the way)

Here is my code at the moment (I am aware queryForTable is an override so is being called regardless, so is there a way to change this to a normal func?) :

override func viewDidLoad() {

    // ideally want something like "if getX'IsComplete' then queryForTable() and self.loadObjects()"

    retrieveFirstX()

    let delay = 3.0 * Double(NSEC_PER_SEC) // retrieveFirstX must load within 3.0 for table to populate without needing to pullToRefresh
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
    dispatch_after(time, dispatch_get_main_queue(), {

        self.queryForTable()
        self.loadObjects()
    })
}

var X = PFObject(className: "X")

func retrieveFirstX() -> Bool {

    let xQuery = PFQuery(className: "X")
    xQuery.orderByDescending("createdAt")
    xQuery.getFirstObjectInBackgroundWithBlock {
        (object: PFObject?, error: NSError?) -> Void in
        if error == nil {

            self.X = object!
        }
    }
    return true
}

 override func queryForTable() -> PFQuery {

    let xRelation = X.relationForKey("xPosts") as PFRelation!
    let relationQuery = xRelation.query()

    let xPostsQuery = PFQuery(className: "Posts")
    xPostsQuery.includeKey("postUser")
    xPostsQuery.whereKey("objectId", matchesKey: "objectId", inQuery: relationQuery)
    xPostsQuery.cachePolicy = .NetworkElseCache
    xPostsQuery.orderByDescending("createdAt")
    return xPostsQuery
}

Do I need to use completion handlers, and if so how do I do that as I have never used them before?

Thanks in advance!


Solution

  • A completion handler sounds right, something like:

    override func viewDidLoad() {
        let completionHandler = {
            self.queryForTable()
            self.loadObjects()
        }
        retrieveFirstX(completionHandler)
    }
    
    func retrieveFirstX(completion: ()->()) -> Bool {
        let xQuery = PFQuery(className: "X")
        xQuery.orderByDescending("createdAt")
        xQuery.getFirstObjectInBackgroundWithBlock {
            (object: PFObject?, error: NSError?) -> Void in
            if error == nil {
                self.X = object!
                completion()
            }
        }
        return true
    }