void函数中出现意外的非void返回值,返回多个值

时间:2017-08-16 07:51:02

标签: ios swift alamofire

我对我创建的函数有问题,我想返回多个值,但似乎,我一直收到此错误

  

void函数中出现意外的非void返回值

func calculateDistance(_ firstLat: Double, _ firstLong: Double, _ secondLat: Double, _ secondLong: Double) -> (Double, Double, String) {

        let URL = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=\(firstLat),\(firstLong)&destinations=\(secondLat),\(secondLong)&key=KEYID"
        Alamofire.request(URL)
            .responseJSON { response in

                if let value = response.result.value {
                    let json = JSON(value)
                    let distance = json["rows"][0]["elements"][0]["distance"]["value"].double! / 1000 // Double
                    let price = distance * 1.0 // Double
                    let duration = json["rows"][0]["elements"][0]["duration"]["text"] // String
                    return (distance, price, duration) // Keep getting this error on this line
                }
        }


    }

我做错了什么?我返回正确的数据类型。

3 个答案:

答案 0 :(得分:3)

这里的第一个错误是Alamofire.request...是异步的。因此,您无法在函数中返回使用该值获取的值。

您收到错误的原因是因为您在尝试返回时不再使用此功能。您所处的功能是Alamofire请求的完成处理程序。

为了从中获取一些东西,你必须将它传递给你自己的完成处理程序。像这样......

func calculateDistance(_ firstLat: Double, _ firstLong: Double, _ secondLat: Double, _ secondLong: Double, completionHandler: @escaping (Double, Double, String) -> ()) {

    let URL = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=\(firstLat),\(firstLong)&destinations=\(secondLat),\(secondLong)&key=KEYID"
        Alamofire.request(URL).responseJSON { response in
            if let value = response.result.value {
                let json = JSON(value)
                let distance = json["rows"][0]["elements"][0]["distance"]["value"].double! / 1000 // Double
                let price = distance * 1.0 // Double
                let duration = json["rows"][0]["elements"][0]["duration"]["text"] // String
                completionHandler(distance, price, duration) // Keep getting this error on this line
            }
        }
    }
}

签名(Double, Double, String) -> ()是一个接收两个Doubles和一个String的函数。当您从网络获取数据时,您将调用此函数。

然后你会称之为......

calculateDistance(1, 2, 3) { (distance, price, duration) in
    // do something with the distance price and duration
}

这里只是另一个注意事项......使用_压缩函数中的参数名称是非常糟糕的做法。对于第一个参数(如果从函数名称中显而易见)它是什么(可能),但不要对以下参数执行此操作。

答案 1 :(得分:0)

您需要使用块来返回值

func calculateDistance(_ firstLat: Double, _ firstLong: Double, _ secondLat: Double, _ secondLong: Double, completion: @escaping (Double, Double, String)->()) {

        let URL = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=\(firstLat),\(firstLong)&destinations=\(secondLat),\(secondLong)&key=KEYID"
        Alamofire.request(URL)
            .responseJSON { response in

                if let value = response.result.value {
                    let json = JSON(value)
                    let distance = json["rows"][0]["elements"][0]["distance"]["value"].double! / 1000 // Double
                    let price = distance * 1.0 // Double
                    let duration = json["rows"][0]["elements"][0]["duration"]["text"] // String
                    completion(distance, price, duration) // return values
                }
        }


    }

要获得该值,请使用:

//call the method
 calculateDistance(SomeDouble, SomeDouble, SomeDouble, SomeDouble) {(distance, price, duration) in
         //here you can use those values
    }

答案 2 :(得分:0)

return语句用于闭包,它是Alamofire请求的回调而不是calculateDistance函数。在收到请求的响应时执行此闭包。由于请求是异步的,因此在函数calculateDistance返回后很久就会执行此闭包。

相反,您可以使用委托模式或完成处理程序。

func calculateDistance(_ firstLat: Double, _ firstLong: Double, _ secondLat: Double, _ secondLong: Double, completion: @escaping (Double, Double, String) -> ()) {
    Alamofire.request(...).responseJSON {
        parse response
        completion(distance, price, duration)
    }
}