In one of my apps I need to add an ability to find a city by its name. I am using CLGeocoder to achieve this and I want it to have a behaviour identical to iOS
I was facing this problem too here on Brazil, só I made a terrible solution for that:
public func getLatLonFrom(address: String, completion:@escaping ((CLLocation?, NSError?)->Void)) {
//LCEssentials.printInfo(title: "LOCATION", msg: "CEP: \(address)")
let geoCoder = CLGeocoder()
let params: [String: Any] = [
CNPostalAddressPostalCodeKey: address,
CNPostalAddressISOCountryCodeKey: "BR"
]
geoCoder.geocodeAddressString(address) { (placemarks, error) in
//LCEssentials.printInfo(title: "LOCATION", msg: "PLACEMARKS FIRST: \(placemarks?.debugDescription)")
if let locais = placemarks {
guard let location = locais.first?.location else {
let error = NSError(domain: LCEssentials().DEFAULT_ERROR_DOMAIN, code: LCEssentials().DEFAULT_ERROR_CODE, userInfo: [ NSLocalizedDescriptionKey: "Address not found" ])
completion(nil, error)
return
}
completion(location, nil)
}else{
geoCoder.geocodeAddressDictionary(params) { (placemarks, error) in
//LCEssentials.printInfo(title: "LOCATION", msg: "PLACEMARKS: \(placemarks?.debugDescription)")
guard let founded = placemarks, let location = founded.first?.location else {
let error = NSError(domain: LCEssentials().DEFAULT_ERROR_DOMAIN, code: LCEssentials().DEFAULT_ERROR_CODE, userInfo: [ NSLocalizedDescriptionKey: "Address not found" ])
completion(nil, error)
return
}
completion(location, nil)
}
}
}
}
I force the Country Code to BR ( Brazil ) and then i can find the address by ZIP CODE. If it return NIL for placemarks on geocodeAddressString then i call the geocodeAddressDictionary and i receive the correct result.
This solution can cover major zip code from BR. It is a mess code, but for now it works.
Future projects i will use Google Maps.