swifttimezonecompletionhandlerclgeocoderclplacemark

Swift CLGeocoder to get TimeZone


I'm afraid I likely have the completion handler all messed up. What I am trying to do is use latitude and longitude to get a TimeZone. I want the entire function to return the value with a type TimeZone. The following code works, as in I can get the correct timeZone but it's at the returning stage that it falls apart.

func getTimeZone(location: CLLocationCoordinate2D, completion: () -> TimeZone) -> TimeZone {
    
    var timeZone = TimeZone(identifier: "timeZone")
    var placemark: CLPlacemark?
    let cllLocation = CLLocation(latitude: location.latitude, longitude: location.longitude)
    let geocoder = CLGeocoder()
    
    geocoder.reverseGeocodeLocation(cllLocation) { placemarks, error in
        
        if let error = error {
            print(error.localizedDescription)
        } else {
            
            if let placemarks = placemarks {
                placemark = placemarks.first
            }
        }
        DispatchQueue.main.async {
            
            if let optTime = placemark?.timeZone {
                timeZone = optTime
            }

            return completion()
        }
    }
}

Solution

  • I think there is a problem with the completion implementation. Try to change it to something like this:

    func getTimeZone(location: CLLocationCoordinate2D, completion: @escaping ((TimeZone) -> Void)) {
        let cllLocation = CLLocation(latitude: location.latitude, longitude: location.longitude)
        let geocoder = CLGeocoder()
    
        geocoder.reverseGeocodeLocation(cllLocation) { placemarks, error in
    
            if let error = error {
                print(error.localizedDescription)
    
            } else {
                if let placemarks = placemarks {
                    if let optTime = placemarks.first!.timeZone {
                        completion(optTime)
                    }
                }
            }
        }
    }
    

    Then you can call the function like this:

    getTimeZone(location: CLLocationCoordinate2D(latitude: CLLocationDegrees(9.62), longitude: CLLocationDegrees(84.62))) { timeZone in
        print("Time zone: \(timeZone)")
    }