我在数据库中有任务模型(使用领域),它由id,标题,距离,经度,纬度,customerAddress组成。我正在尝试更新我的任务距离。我是新手,所以我不明白如何修复geoCoder.geocodeAddressString闭包,以便所有任务都会随着它们的距离而更新。 (当任务没有纬度和经度时,我会通过使用geocodeAddressString检查任务是否具有客户地址
func updateTasksDistance() {
// get tasks for db
guard let tasks = Task.getAllUserTasks() else { return }
// last tracked location
guard let lastLocation = lastLocation else { return }
let myLocation = CLLocation(latitude: lastLocation.coordinate.latitude, longitude: lastLocation.coordinate.longitude)
var distance = 0
tasks.forEach({ (task) in
// check if task has longitude and latitude
if let lat = Double(task.latitude), let long = Double(task.longitude), lat != 0 && long != 0 {
let taskLocation = CLLocation(latitude: lat, longitude: long)
distance = Int(taskLocation.distance(from: myLocation))
} else if !task.customerAddress.isEmpty { // check if task has address
geoCoder.geocodeAddressString(task.customerAddress) { placemarks, _ in
if let placemark = placemarks?.first, let location = placemark.location {
self.taskLocationCoordinate = CLLocation(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude )
}
}
}
// check if we have closure location??
if let taskLocation = taskLocationCoordinate {
distance = Int(CLLocation(latitude: taskLocation.coordinate.latitude, longitude: taskLocation.coordinate.longitude).distance(from: myLocation))
taskLocationCoordinate = nil
}
// update my distance to task
updateTaskDistanceDb(task: task, with: distance)
// reset distance
distance = 0
})
}
// update task distance in db
fileprivate func updateTaskDistanceDb(task: Task, with distance: Int) {
let realm = try? Realm()
if let realm = realm {
do {
try realm.write {
task.distance = distance
}
} catch {
print("error")
}
}
}
当前结果:在未调用闭包的情况下,距离可以正确更新,但是在调用闭包时,我会得到混乱的结果
预期结果:相对于地雷的所有任务距离均已正确更新
答案 0 :(得分:0)
使用以下代码解决了此问题:
fileprivate func geoCode(addresses: [String], results: [CLPlacemark] = [], completion: @escaping ([CLPlacemark]) -> Void ) {
guard let address = addresses.first else {
completion(results)
return
}
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(address) { placemarks, _ in
var updatedResults = results
if let placemark = placemarks?.first {
updatedResults.append(placemark)
}
let remainingAddresses = Array(addresses[1..<addresses.count])
self.geoCode(addresses: remainingAddresses, results: updatedResults, completion: completion)
}
}
func updateTasksDistance() {
// get tasks for db
guard let tasks = Task.getAllUserTasks() else { return }
// last tracked location
guard let lastLocation = lastLocation else { return }
let myLocation = CLLocation(latitude: lastLocation.coordinate.latitude, longitude: lastLocation.coordinate.longitude)
let dispatchGroup = DispatchGroup()
for task in tasks where !task.customerAddress.isEmpty {
let addresses = [task.customerAddress]
dispatchGroup.enter()
geoCode(addresses: addresses) { results in
guard let customerAdress = results.first else { return }
guard let customerLocatin = customerAdress.location else { return }
let taskLocation = CLLocation(latitude: customerLocatin.coordinate.latitude,
longitude: customerLocatin.coordinate.longitude )
// do additional sutff
dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: DispatchQueue.main, execute: {
// got all the address
}
})
}
递归地理编码功能有助于计算所有坐标,dispatchGroup.notify用于等待对所有地址进行地理编码。