geocodeAddressString not working for some addresses
I think you are expecting the iOS geocoding to perform as well as Google's geocoding. It certainly won't, though.
It is not working because Apple's geocoding is not as good as Google's geocoding.
To see what I mean, put
Kloten Airport, Sweden
into the iOS Maps app. It gives nothing. Put it into maps.google.com and you see the airport.
CLGeocoder().geocodeAddressString error codes
You need to cast the error as CLError
and then switch the error code
:
if let error = error as? CLError {
switch error.code {
case .locationUnknown:
print("locationUnknown: location manager was unable to obtain a location value right now.")
case .denied:
print("denied: user denied access to the location service.")
case .promptDeclined:
print("promptDeclined: user didn’t grant the requested temporary authorization.")
case .network:
print("network: network was unavailable or a network error occurred.")
case .headingFailure:
print("headingFailure: heading could not be determined.")
case .rangingUnavailable:
print("rangingUnavailable: ranging is disabled.")
case .rangingFailure:
print("rangingFailure: a general ranging error occurred.")
default : break
}
}
How to fix geocodeAddressString closure in for each
Fixed this issue by using this code:
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
}
})
}
Recursive geocode function helped to calculate all coordinates and dispatchGroup.notify is for waiting till all addresses are geocoded.
geocoder.geocodeAddressString no longer works with swift update today
Use geocodeAddressString
this way:
geocoder.geocodeAddressString(address, completionHandler: {(placemarks: [CLPlacemark]?, error: NSError?) -> Void in
})
And it will work fine.
Related Topics
Swift Error: Failed to Get Module 'My_App' from Ast Context
Is There Any Difference at All Between Suffix(From:) and Dropfirst(_:)
Iocreateplugininterfaceforservice Returns Mysterious Error
"The Requested Snapshot Version Is Too Old." Error in Firestore
Where Do I Register a Valuetransformer in Swift
Apple Turicreate Always Return The Same Label
Preventing Nsurlsession Default Http Headers
Ibdesignable View Not Rendering
Scenekit - Why Scnlight Created Automatically in Scnscene
Set Multiple Arrow Directions on UIpopovercontroller in Swift
How to Add More Cases for Enum in Swift
Navigation Bar Items After Push from Swiftui to UIkit
Swift iOS14 Datepicker Text Alignment
Weak Reference to Closure in Swift
Swiftycam Capture Session Is Not Running