问题
I found one way to send request:
A Google Maps Geocoding API request takes the following form:
https://maps.googleapis.com/maps/api/geocode/outputFormat?parameters where outputFormat may be either of the following values:
json (recommended) indicates output in JavaScript Object Notation (JSON); or xml indicates output in XML To access the Google Maps Geocoding API over HTTP, use:
But it's really inconvenient, is there any native way in swift?
I looked into GMSGeocoder interface and only reverse geocoding can be done by it's API.
回答1:
As others have pointed out, there is not a predefined method to do the search, but you can use network request to access the Google Geocoding API yourself:
func performGoogleSearch(for string: String) {
strings = nil
tableView.reloadData()
var components = URLComponents(string: "https://maps.googleapis.com/maps/api/geocode/json")!
let key = URLQueryItem(name: "key", value: "...") // use your key
let address = URLQueryItem(name: "address", value: string)
components.queryItems = [key, address]
let task = URLSession.shared.dataTask(with: components.url!) { data, response, error in
guard let data = data, let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200, error == nil else {
print(String(describing: response))
print(String(describing: error))
return
}
guard let json = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any] else {
print("not JSON format expected")
print(String(data: data, encoding: .utf8) ?? "Not string?!?")
return
}
guard let results = json["results"] as? [[String: Any]],
let status = json["status"] as? String,
status == "OK" else {
print("no results")
print(String(describing: json))
return
}
DispatchQueue.main.async {
// now do something with the results, e.g. grab `formatted_address`:
let strings = results.compactMap { $0["formatted_address"] as? String }
...
}
}
task.resume()
}
回答2:
No, there is no native way in the Google Maps SDK for iOS.
This is a very popular feature request though, see: Issue 5170: Feature request: Forward geocoding (from address to coordinates)
回答3:
If you are just looking for a Geocoding solution you could look into a little open source project I built. It is very lightweight and uses OpenStreetMap's geocoding API called Nominatim. Check it out here: https://github.com/caloon/NominatimSwift
You can even search for landmarks.
Geocoding addresses and landmarks:
Nominatim.getLocation(fromAddress: "The Royal Palace of Stockholm", completion: {(error, location) -> Void in
print("Geolocation of the Royal Palace of Stockholm:")
print("lat = " + (location?.latitude)! + " lon = " + (location?.longitude)!)
})
回答4:
Unfortunately, there is no way to do that as native. I hope that function will help.
func getAddress(address:String){
let key : String = "YOUR_GOOGLE_API_KEY"
let postParameters:[String: Any] = [ "address": address,"key":key]
let url : String = "https://maps.googleapis.com/maps/api/geocode/json"
Alamofire.request(url, method: .get, parameters: postParameters, encoding: URLEncoding.default, headers: nil).responseJSON { response in
if let receivedResults = response.result.value
{
let resultParams = JSON(receivedResults)
print(resultParams) // RESULT JSON
print(resultParams["status"]) // OK, ERROR
print(resultParams["results"][0]["geometry"]["location"]["lat"].doubleValue) // approximately latitude
print(resultParams["results"][0]["geometry"]["location"]["lng"].doubleValue) // approximately longitude
}
}
}
回答5:
Alamofire and Google's Geodecode API
Swift 4
func getAddressFromLatLong(latitude: Double, longitude : Double) {
let url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=\(latitude),\(longitude)&key=YOUR_API_KEY_HERE"
Alamofire.request(url).validate().responseJSON { response in
switch response.result {
case .success:
let responseJson = response.result.value! as! NSDictionary
if let results = responseJson.object(forKey: "results")! as? [NSDictionary] {
if results.count > 0 {
if let addressComponents = results[0]["address_components"]! as? [NSDictionary] {
self.address = results[0]["formatted_address"] as? String
for component in addressComponents {
if let temp = component.object(forKey: "types") as? [String] {
if (temp[0] == "postal_code") {
self.pincode = component["long_name"] as? String
}
if (temp[0] == "locality") {
self.city = component["long_name"] as? String
}
if (temp[0] == "administrative_area_level_1") {
self.state = component["long_name"] as? String
}
if (temp[0] == "country") {
self.country = component["long_name"] as? String
}
}
}
}
}
}
case .failure(let error):
print(error)
}
}
}
回答6:
You can send a request through URL session of the address using Place Search of Google Places API and then parse the json result. It may not be perfect but you can get more information other than coordinates.
回答7:
There is no native way in the Google Maps API iOS SDK. As has been mentioned in other answers, it's been a requested feature for years.
One thing to remember is that Google Maps APIs are mostly focused on creating maps: that's a primary goal.
You have to use the URL-based API calls or some other service. For instance, a different service called SmartyStreets has an iOS SDK that has native support for forward geocoding. Here's the example code for Swift from their iOS SDK documentation page:
// Swift: Sending a Single Lookup to the US ZIP Code API
package examples;
import Foundation
import SmartystreetsSDK
class ZipCodeSingleLookupExample {
func run() -> String {
let mobile = SSSharedCredentials(id: "SMARTY WEBSITE KEY HERE", hostname: "HOST HERE")
let client = SSZipCodeClientBuilder(signer: mobile).build()
// Uncomment the following line to use Static Credentials
// let client = SSZipCodeClientBuilder(authId: "YOUR AUTH-ID HERE", authToken: "YOUR AUTH-TOKEN HERE").build()
let lookup = SSZipCodeLookup()
lookup.city = "Mountain View"
lookup.state = "California"
do {
try client?.send(lookup)
} catch let error as NSError {
print(String(format: "Domain: %@", error.domain))
print(String(format: "Error Code: %i", error.code))
print(String(format: "Description: %@", error.localizedDescription))
return "Error sending request"
}
let result: SSResult = lookup.result
let zipCodes = result.zipCodes
let cities = result.cities
var output: String = String()
if (cities == nil && zipCodes == nil) {
output += "Error getting cities and zip codes."
return output
}
for city in cities! {
output += "\nCity: " + (city as! SSCity).city
output += "\nState: " + (city as! SSCity).state
output += "\nMailable City: " + ((city as! SSCity).mailableCity ? "YES" : "NO") + "\n"
}
for zip in zipCodes! {
output += "\nZIP Code: " + (zip as! SSZipCode).zipCode
output += "\nLatitude: " + String(format:"%f", (zip as! SSZipCode).latitude)
output += "\nLongitude: " + String(format:"%f", (zip as! SSZipCode).longitude) + "\n"
}
return output
}
}
Full disclosure: I have worked for SmartyStreets.
来源:https://stackoverflow.com/questions/40971633/how-to-geocode-address-by-google-maps-ios-api