0

恐怕我可能把完成处理程序都搞砸了。我想要做的是使用纬度和经度来获得时区。我希望整个函数返回 TimeZone 类型的值。以下代码有效,因为我可以获得正确的 timeZone 但它在返回阶段分崩离析。

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()
        }
    }
}
4

3 回答 3

2

我认为完成实现存在问题。尝试将其更改为以下内容:

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)
                }
            }
        }
    }
}

然后你可以像这样调用函数:

getTimeZone(location: CLLocationCoordinate2D(latitude: CLLocationDegrees(9.62), longitude: CLLocationDegrees(84.62))) { timeZone in
    print("Time zone: \(timeZone)")
}
于 2021-10-08T18:11:55.460 回答
1

你几乎是对的。摆脱返回值。您不能从这样的异步函数返回函数结果。

相反,调用者传入一个完成处理程序,该处理程序在返回结果时执行:

func getTimeZone(location: CLLocationCoordinate2D, completion:  @escaping (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
            }
            completion(timeZone)
        }
    }
}

然后,使用它:

getTimeZone(location: someLocation) { timeZone in
   // This code will execute once the time zone is calculated.
   print("The time zone for that location is \(timeZone.description)")
}
于 2021-10-08T18:09:47.740 回答
0

reverseGeocodeLocation当您涉及异步时,为什么要尝试返回值getTimeZone

func getTimeZone(location: CLLocationCoordinate2D, completion: @escaping (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 {
                    completion(optTime)
                }
            }
        }
    }

最后用它作为

        getTimeZone(location: your_location_coordinates_here) {[weak self] timeZone in
            debugPrint(timeZone)
        }
于 2021-10-08T18:09:33.293 回答