Swift CLGeocoder 获取时区
Swift CLGeocoder to get TimeZone
恐怕我可能把完成处理程序搞砸了。我想要做的是使用纬度和经度来获取时区。我希望整个函数 return 类型为 TimeZone 的值。以下代码有效,因为我可以获得正确的时区,但它在 returning 阶段崩溃了。
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()
}
}
}
当 getTimeZone
中包含异步 reverseGeocodeLocation
时,为什么要尝试 return 一个值
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)
}
你几乎是对的。去掉 return 值。您不能 return 像这样的异步函数的函数结果。
相反,调用者传入一个完成处理程序,该处理程序在结果为 returned 时执行:
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)")
}
我认为完成实现有问题。试着把它改成这样:
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)")
}
恐怕我可能把完成处理程序搞砸了。我想要做的是使用纬度和经度来获取时区。我希望整个函数 return 类型为 TimeZone 的值。以下代码有效,因为我可以获得正确的时区,但它在 returning 阶段崩溃了。
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()
}
}
}
当 getTimeZone
reverseGeocodeLocation
时,为什么要尝试 return 一个值
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)
}
你几乎是对的。去掉 return 值。您不能 return 像这样的异步函数的函数结果。
相反,调用者传入一个完成处理程序,该处理程序在结果为 returned 时执行:
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)")
}
我认为完成实现有问题。试着把它改成这样:
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)")
}