JoeW467 JoeW467 - 3 months ago 12
iOS Question

What does this code in Swift do?

I'm following a raywenderlich.com tutorial on using the Google Maps iOS SDK. I came across this piece of code which is halfway down this link here: https://www.raywenderlich.com/109888/google-maps-ios-sdk-tutorial.

I am familiar with Swift but I do not get what the piece of code after geocoder.reverseGeocodeCoordinate(coordinate) does; specifically, how can you just place the curly brackets right after the method call and what does it accomplish? I am asking this in terms of Swift syntax.

func reverseGeocodeCoordinate(coordinate: CLLocationCoordinate2D) {

// 1
let geocoder = GMSGeocoder()

// 2
geocoder.reverseGeocodeCoordinate(coordinate) { response, error in
if let address = response?.firstResult() {

// 3
let lines = address.lines as! [String]
self.addressLabel.text = lines.joinWithSeparator("\n")

// 4
UIView.animateWithDuration(0.25) {
self.view.layoutIfNeeded()
}
}
}
}

Answer

This is called a "trailing closure" or "trailing closure syntax". It's described in Apple's docs here:

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID102

In summary, if the last parameter of a method or function is a closure, you can provide it immediately after the closing ) of the function call and the previous arguments. Example:

func sendMessage(text:String, withCallback:(Bool)->()) {
    // Implementation
}

let message = "hello"
sendMessage(message) { 
    let result = $0 ? "Suceeded" : "Failed"
    print(result)
}

If a function take only one parameter and that parameter is a closure, then you don't need to use () at all and can just pass the closure immediately after the function name. For example see how this filter method is called:

let boolArray = [true, true, false, true, false]
let filtered = boolArray.filter { $0 == false }  // Only the falses