0

How can I wait until data is retrieved from parse.com?

This is the function I have that returns an empty string since the response from parse.com is too slow. If I put a breakpoint inside the success area it will break "long" after the data is needed. I guess there is a way to get the data synchronous so it will wait?

func getObjectId(localPersonId:NSString) -> NSString{
    var currentObjectId:NSString = ""

    var query = PFQuery(className:"myClass")
    query.whereKey("personId", equalTo:localPersonId)
    query.whereKey("groupId", equalTo:self.currentGroupId)
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]!, error: NSError!) -> Void in
        if error == nil {
            // should not use a for loop since this should 
            // only return one row
            for object in objects {
                currentObjectId = object["objectId"] as NSString
            }
        } else {
            // Log details of the failure
            NSLog("Error: %@ %@", error, error.userInfo!)
        }
    }

    return currentObjectId
}

In this case the getObjectId function will return an empty string. Anyone?

TommyF
  • 381
  • 1
  • 7
  • 22
  • You'll need to make your `getObjectId function` asynchronous. Right now the line `return currentObjectId` is being executed before the query has finished. – ardrian Feb 23 '15 at 13:45
  • Yes, that is the problem. How can I make the function asynchronous? – TommyF Feb 23 '15 at 14:35
  • See here http://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function – danh Feb 23 '15 at 15:50
  • Sadly, that link did not make me see the light with my issue... I thought I maybe should use something other than findObjectsInBackgroundWithBlock. Not sure. Too much of a newbie to know what is best approach for this. – TommyF Feb 23 '15 at 16:47
  • You won't be able to avoid using one of the Async methods. If you were using Objective-C I could write you up an answer, unfortunately I'm not up to scratch with Swift yet. Have you looked at the tutorials on the Parse website, perhaps they have updated one of their iOS example/tutorial apps to use Swift? – ardrian Feb 24 '15 at 03:00
  • Well, it turns out that 'findObjectsInBackgroundWithBlock' actually is an Async method. And what I probably should use in this situation is a Sync method like 'findObject'. I'll try it out and see if it works. – TommyF Feb 24 '15 at 12:45
  • @TommyF it is fine to use a sync method, but make sure you don't do this from your main thread, otherwise you'll block the UI, and the app will appear to be unresponsive to the user. – ardrian Feb 24 '15 at 15:30

1 Answers1

2

I realize this is 3 months old but although the Parse docs are incredibly good/useful, there isn't a whole lot out there answering IOS Parse related questions.

This should work. It uses a completion handler, which is a simple way of dealing with this issue.

(for more on completion handlers in asynch context: https://thatthinginswift.com/completion-handlers/ )

func getObjectId(localPersonId:NSString, completionHandler: (currentObjectId: [String]) -> ()){

    var currentObjectId:NSString = ""

    var query = PFQuery(className:"myClass")
    query.whereKey("personId", equalTo:localPersonId)
    //query.whereKey("groupId", equalTo:self.currentGroupId)
    query.findObjectsInBackgroundWithBlock {
        (objects, error) -> Void in
        if error == nil {
            // should not use a for loop since this should
            // only return one row
            for object in objects {
                completionHandler(currentObjectId: currentObjectId)
            }
        } else {
            // Log details of the failure
            NSLog("Error: %@ %@", error!, error!.userInfo!)
        }
    }
}
user3498976
  • 157
  • 3
  • 13
  • Yeah, I while since I had this problem. I have probably done a hack for this to work since I got no response, but I'll have a look at my old code and have a look. Anyway; great to learn about the completionHandler :) – TommyF Jun 12 '15 at 11:17