-2

I am getting the error "Unexpected non-void return value in void function", although I am providing return type in the function.

Following is my code for reference:

func getLatDestination() -> Double {
    var params = [String: Any]()
    params[ParametersKeys.access_token] = KeyChain.getAccessToken()!
    params[ParametersKeys.address] = googlePlaceObject?.results.first?.formattedAddress
    params[ParametersKeys.latitude] = googlePlaceObject?.results.first?.geometry.location.lat
    params[ParametersKeys.longitude] = googlePlaceObject?.results.first?.geometry.location.lng
    params[ParametersKeys.googlePlaceId] = googlePlaceObject?.results.last?.placeId
    params[ParametersKeys.login_type] = 1
        
    AuthManager.shared.saveAddressAsWorkHome(params) { (response) in
        if response.flag == RESPONSE_FLAGS.flag_143 {
            if let addressData = response.response["addresses"] as? [[String: Any]] {
                return  addressData[0]["lat"]
            }
        }
    }
}

and I am getting value of addressData[0]["lat"] as Optional(51.5050755) in console.

Pardon me if it is very basic question as I am beginner to swift.

gcharita
  • 7,729
  • 3
  • 20
  • 37

2 Answers2

4

I think AuthManager.shared.saveAddressAsWorkHome(params) { (response) in this is asynchronous closure and you are try to return a value in it so you getting this error.

You can not return from asynchronous function directly. You have to add a completion handler on your method and return the value from async in completion handler

So you have to change your function

func getLatDestination(completion : @escaping (Double) -> ()){
var params = [String: Any]()
params[ParametersKeys.access_token] = KeyChain.getAccessToken()!
params[ParametersKeys.address] = googlePlaceObject?.results.first?.formattedAddress
params[ParametersKeys.latitude] = googlePlaceObject?.results.first?.geometry.location.lat
params[ParametersKeys.longitude] = googlePlaceObject?.results.first?.geometry.location.lng
params[ParametersKeys.googlePlaceId] = googlePlaceObject?.results.last?.placeId
params[ParametersKeys.login_type] = 1
    
AuthManager.shared.saveAddressAsWorkHome(params) { (response) in
    if response.flag == RESPONSE_FLAGS.flag_143 {
        if let addressData = response.response["addresses"] as? [[String: Any]] {
                    completion(addressData[0]["lat"])

        }
    }
}

And when you call your function

getLatDestination(completion: {ret in
        print(ret) 
    })
Omer Tekbiyik
  • 4,255
  • 1
  • 15
  • 27
3

You can't do what you are trying to do. The function saveAddressAsWorkHome() is asynchronous. When you call it, it returns immediately before the result is available. At some future time the save finishes and your completion handler code is excuted.

You can't return from your function inside the completion handler.

You need to refactor your getLatDestination() function to take a completion handler, and call that once the result is available.

You should read up on async functions and completion handlers in Swift.

The rewritten function might look like this:

func getLatDestination(completion: @escaping (Double?)->())  {
    var params = [String: Any]()
    params[ParametersKeys.access_token] = KeyChain.getAccessToken()!
    params[ParametersKeys.address] = googlePlaceObject?.results.first?.formattedAddress
    params[ParametersKeys.latitude] = googlePlaceObject?.results.first?.geometry.location.lat
    params[ParametersKeys.longitude] = googlePlaceObject?.results.first?.geometry.location.lng
    params[ParametersKeys.googlePlaceId] = googlePlaceObject?.results.last?.placeId
    params[ParametersKeys.login_type] = 1
        
    AuthManager.shared.saveAddressAsWorkHome(params) { (response) in
        if response.flag == RESPONSE_FLAGS.flag_143 {
            if let addressData = response.response["addresses"] as? [[String: Any]] {
                completion(addressData[0]["lat"] as? Double)
            }
        }
        else { completion(nil) }
    }
}

The function `getLatDestination() now takes a completion handler, a block of code. That completion handler, in turn, takes an Optional Double as a result. (It looks like your async function returns a dictionary, and you can't be sure it will contain the key/values and types that you are expecting.

Duncan C
  • 128,072
  • 22
  • 173
  • 272