Swift中通过邮政编码获取坐标遇请求拒绝错误的技术求助
解决Google Geocoding API的REQUEST_DENIED错误(IP/应用未授权)
从你遇到的错误信息和代码来看,这个问题的核心是你的API密钥没有被正确配置,无法允许当前请求的来源。错误里明确提到了两个关键点:请求来自IP地址0.0.0.0(本地测试时常见的无效IP识别),且请求的referer为空,这都是Google API密钥授权验证不通过的典型原因。下面给你一步步的解决思路:
一、先检查Google Cloud控制台的API密钥授权配置
这是最关键的一步,很多开发者都会在这里踩坑:
- 登录Google Cloud控制台,找到你正在使用的Geocoding API密钥
- 在「应用限制」区域:
- 如果你是iOS应用,一定要选择「iOS应用」,然后添加你的App Bundle ID(比如
com.yourcompany.yourapp),这样只有你的应用能使用这个密钥 - 要是你正处于本地测试阶段,暂时可以把应用限制设为「无」(但上线前务必改回具体的应用限制,防止密钥被滥用)
- 如果你是iOS应用,一定要选择「iOS应用」,然后添加你的App Bundle ID(比如
- 在「API限制」区域,确保只勾选了「Geocoding API」,避免密钥被其他未授权的API调用消耗额度
- 注意:0.0.0.0是无效的IP地址,Google无法识别这个作为授权来源,如果是用IP限制的测试场景,要添加你的公网IP地址
二、修复代码里的问题
你的代码有几个可以优化的地方,既能解决授权问题,也能让逻辑更合理:
- 确认密钥类型正确:确保
Global.kGoogleApiKey.strPlaceAPIKey是Geocoding API的密钥,虽然有时候Places API密钥也能通用,但最好对应使用专门的Geocoding密钥 - 处理异步请求的返回:你现在的函数直接返回(0.0, 0.0),但网络请求是异步的,这个写法完全拿不到真实的坐标结果!必须用闭包或者Async/Await来异步返回结果,我给你改了一下代码:
调用的时候就可以这样拿到结果:func getLocationFromAddress(zipCode: String, completion: @escaping (CLLocationCoordinate2D?) -> Void) { let strUrl = "https://maps.googleapis.com/maps/api/geocode/json?address=\(zipCode)&key=\(Global.kGoogleApiKey.strPlaceAPIKey)&sensor=false" // 安全处理URL编码,避免强制解包崩溃 guard let escapedString = strUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { completion(nil) return } AFAPIMaster.sharedAPIMaster.getLatLongCallApi_Completion(strGetURL: escapedString, params: nil, showLoader: true, enableInteraction: false, viewObj:self.view, onSuccess: { result in // 解析返回的JSON数据,提取坐标 guard let dict = result as? [String: Any], let results = dict["results"] as? [[String: Any]], let firstResult = results.first, let geometry = firstResult["geometry"] as? [String: Any], let location = geometry["location"] as? [String: Double] else { completion(nil) return } let coordinate = CLLocationCoordinate2D(latitude: location["lat"] ?? 0.0, longitude: location["lng"] ?? 0.0) completion(coordinate) }, onFailure: { error in // 不要忽略失败回调,打印错误信息方便排查 print("获取坐标失败:\(error.localizedDescription)") completion(nil) }) }getLocationFromAddress(zipCode: "100001") { coordinate in if let coord = coordinate { print("拿到坐标:\(coord.latitude), \(coord.longitude)") } else { print("获取坐标失败") } } - 添加请求头(可选):虽然iOS应用主要靠Bundle ID限制授权,但如果需要的话,可以给AFNetworking的请求添加Referer头:
AFAPIMaster.sharedAPIMaster.requestSerializer.setValue("com.yourcompany.yourapp", forHTTPHeaderField: "Referer")
三、确认Geocoding API已启用
别忘了在Google Cloud控制台的API库中,确认「Geocoding API」已经被启用——很多时候密钥配置没问题,但API没开也会导致请求被拒绝。
你的错误信息和原代码参考
错误信息:
{ "error_message" = "This IP, site or mobile application is not authorized to use this API key. Request received from IP address 0.0.0.0., with empty referer"; results = ( ); status = "REQUEST_DENIED"; }
原代码:
public func getLocationFromAddress(zipCode : String) -> CLLocationCoordinate2D { let lat : Double = 0.0 let lon : Double = 0.0 let strUrl = "https://maps.googleapis.com/maps/api/geocode/json?address=\(zipCode)&key=\(Global.kGoogleApiKey.strPlaceAPIKey)&sensor=false" let escapedString = strUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) AFAPIMaster.sharedAPIMaster.getLatLongCallApi_Completion(strGetURL:escapedString!,params: nil, showLoader: true, enableInteraction: false, viewObj:self.view, onSuccess: { (result) in if let Dict = result as? NSDictionary { print(Dict) } }, onFailure: { }) return CLLocationCoordinate2D(latitude: lat, longitude: lon) }
内容的提问来源于stack exchange,提问作者user8579808
相关产品推荐
相关产品推荐

