1

I have a function in my appDelegate that returns user's current location.

Now I want to call it asynchronously at some other place and I did:

func handleLocation() -> CLLocation {
  let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
  dispatch_async(dispatch_get_global_queue(priority, 0)) {
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    appDelegate.startGPS()
    while (!appDelegate.isLocationFixed()) {
      sleep(1)
    }
    dispatch_async(dispatch_get_main_queue()) {
      return appDelegate.getLocation()
    }
  }
}

but now this line return appDelegate.getLocation() brings me the error:

unexpected non-void return value in void function

I don't know too much about threads in Swift yet, could you help me with fixing this issue?

1 Answer 1

4

The problem is

dispatch_async(dispatch_get_global_queue(priority, 0)) {

and

dispatch_async(dispatch_get_main_queue()) {

are actually creating closures/functions, so any code within them will relate to that function, not

func handleLocation() -> CLLocation {

If you're doing an asynchronous operation within a function, you can't really have a return statement after the asynchronous operation is completed. Instead, you should use a completion handler in your function. e.g.:

func aSyncFunction(completionHandler: (AnyObject) -> ()) {

    //do async opporation

    completionHandler("finished") // call the completion block when finished
}

Here's how I would implement it for your use case:

func handleLocation(completionBlock: (CLLocation?) -> ()) {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {

        guard let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate else {
            dispatch_async(dispatch_get_main_queue()) {
                completionBlock(nil)
            }
            return
        }
        appDelegate.startGPS()
        while (!appDelegate.isLocationFixed()) {
            sleep(1)
        }
        dispatch_async(dispatch_get_main_queue()) {
            completionBlock(appDelegate.getLocation())
        }
    }
}

example usage:

handleLocation { (location: CLLocation?) in
    if let location = location {
         //use valid location
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Hmm so can I just put the body of my function inside of the aSyncFunction? Could you show me exactly how could I do it? I'm not sure if I'm getting the concept right here, thanks!
Added an example for your use case, let me know if you have more questions.
Thank you very much! I just pasted it into my xcode and I'm getting error near this line: handleLocation { (location: CLLocation?) in saying that it expected declaration. Is that a typical error in this case?
Thanks :) The very last thing - I hope - is this error that I'm getting when I try to compile: i.imgur.com/Fbf97lG.png Have you seen it before?
forgot the return in the guard...I think I need more coffee. edited.

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.