gpt4 book ai didi

ios - 尝试使用 reverseGeocodeLocation,但未执行 completionHandler 代码

转载 作者:行者123 更新时间:2023-12-01 16:13:06 26 4
gpt4 key购买 nike

问题是completionHandler block 中的代码永远不会运行;我使用了断点,程序会在构建模式下跳过完成处理程序 block

下面是 PinALandPlaceMark 中使用的两个函数,我的大部分代码都位于

func generateRandomWorldLatitude()-> Double{
let latitude = Double.random(in: -33 ..< 60)
return latitude
}

func generateRandomWorldLongitude()-> Double{
let longitude = Double.random(in: -180 ..< 180)
return longitude
}

func PinALandPlaceMark() -> MKAnnotation {

var LandBasedCountryHasYetToBeFound : (Bool, CLLocationDegrees?, CLLocationDegrees?)
LandBasedCountryHasYetToBeFound = (false,nil,nil)
let randomPinLocation = MKPointAnnotation()

repeat{

if LandBasedCountryHasYetToBeFound == (false,nil,nil){
let latitude: CLLocationDegrees = generateRandomWorldLatitude()
let longitude: CLLocationDegrees = generateRandomWorldLongitude()

let randomCoordinate = CLLocation(latitude: latitude, longitude: longitude)
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(randomCoordinate, completionHandler: { (placemarks, error) -> Void in

if error != nil{print(error)}else{
guard let placemark = placemarks?.first else{return}
//check which placemark property exists, store in the 0 alpha labelForClosure
if let countryExists = placemark.country {

LandBasedCountryHasYetToBeFound = (true,latitude,longitude)
//country = countryExists as String
// viewController.labelForClosure.text = countryExists
print(" Country Exists!: \(countryExists)")
print(" randomCoordinate \(randomCoordinate)")
}
}
})
}

// print("The country found was on land. This statement is \(LandBasedCountryHasYetToBeFound.occursInCountry)")

else{

let coordinatesOfrandomPinLocation = CLLocationCoordinate2D(latitude: LandBasedCountryHasYetToBeFound.1!, longitude: LandBasedCountryHasYetToBeFound.2!)

randomPinLocation.title = ""//LandBasedCountryHasYetToBeFound.countryName
randomPinLocation.coordinate = coordinatesOfrandomPinLocation

// viewController.mapView.addAnnotation(randomPinLocation)

}
}while LandBasedCountryHasYetToBeFound.0 == false
print("randomPin has been returned, now use pin function inside placemark declaration")
return randomPinLocation

}

最佳答案

您的主要问题是您的 CLGeocoder实例保存在循环内的局部变量中;这意味着它将在完成任务之前被释放。

即使反向地理编码完成,您还有其他一些问题也会给您带来问题。

主要的是您正在使用设置在闭包内的 bool 值检查循环终止;闭包将异步执行,因此在找到地址的情况下,在 bool 值设置为 true 之前,循环将执行很多次。

第二个问题与此有关并因此变得更糟;反向地理编码受速率限制。如果您过快提交太多请求,Apple 的服务器将简单地返回一个错误。即使您确实在提交第二个响应之前等待了第一个响应,您随机命中土地的机会也非常低,因此您可能会很快达到此限制。

暂时忽略速率限制问题,您可以使用接受完成处理程序的递归函数,而不是使用循环并尝试 return一个值。

var geoCoder = CLGeocoder()

func pinALandPlaceMark(completion: @escaping (Result<MKAnnotation, Error>) -> Void) {
let latitude: CLLocationDegrees = generateRandomWorldLatitude()
let longitude: CLLocationDegrees = generateRandomWorldLongitude()
let randomCoordinate = CLLocation(latitude: latitude, longitude: longitude)
geocoder.reverseGeocodeLocation(randomCoordinate) { (placemarks, error) in
guard error == nil else {
completion(nil,error)
return error
}
if let placemark = placemarks.first, let _ = placemark.country {
let randomPinLocation = MKPointAnnotation()
randomPinLocation.coordinate = randomCoordinate.coordinate
completionHandler(randomPinLocation,nil)
} else {
pinALandPlaceMark(completion:completion)
}
}
}

我们要做的第一件事是声明一个属性来保存 CLGeocoder实例,使其不被释放。

接下来,此代码检查是否返回了带有国家/地区的地标。如果不是,则函数调用自身,传递相同的完成处理程序,再试一次。如果发生错误,则调用完成处理程序,传递错误

要使用它,你会这样说:
pinALandPlaceMark() { result in
switch result {
case .success(let placemark):
print("Found \(placemark)")
case .failure(let error):
print("An error occurred: \(error)")
}
}

关于ios - 尝试使用 reverseGeocodeLocation,但未执行 completionHandler 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59914591/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com