You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中通过邮政编码获取坐标遇请求拒绝错误的技术求助

解决Google Geocoding API的REQUEST_DENIED错误(IP/应用未授权)

从你遇到的错误信息和代码来看,这个问题的核心是你的API密钥没有被正确配置,无法允许当前请求的来源。错误里明确提到了两个关键点:请求来自IP地址0.0.0.0(本地测试时常见的无效IP识别),且请求的referer为空,这都是Google API密钥授权验证不通过的典型原因。下面给你一步步的解决思路:

一、先检查Google Cloud控制台的API密钥授权配置

这是最关键的一步,很多开发者都会在这里踩坑:

  1. 登录Google Cloud控制台,找到你正在使用的Geocoding API密钥
  2. 在「应用限制」区域:
    • 如果你是iOS应用,一定要选择「iOS应用」,然后添加你的App Bundle ID(比如com.yourcompany.yourapp),这样只有你的应用能使用这个密钥
    • 要是你正处于本地测试阶段,暂时可以把应用限制设为「无」(但上线前务必改回具体的应用限制,防止密钥被滥用)
  3. 在「API限制」区域,确保只勾选了「Geocoding API」,避免密钥被其他未授权的API调用消耗额度
  4. 注意:0.0.0.0是无效的IP地址,Google无法识别这个作为授权来源,如果是用IP限制的测试场景,要添加你的公网IP地址

二、修复代码里的问题

你的代码有几个可以优化的地方,既能解决授权问题,也能让逻辑更合理:

  1. 确认密钥类型正确:确保Global.kGoogleApiKey.strPlaceAPIKey是Geocoding API的密钥,虽然有时候Places API密钥也能通用,但最好对应使用专门的Geocoding密钥
  2. 处理异步请求的返回:你现在的函数直接返回(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("获取坐标失败")
        }
    }
    
  3. 添加请求头(可选):虽然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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:02:58