Google Places自动补全:如何批量获取各地点邮编?
解决方案
核心问题是需要批量处理异步的fetchPlace请求,原代码仅处理了第一个预测结果的详情请求,且错误地将该结果的坐标/邮编复用给了所有预测项。我们可以通过DispatchGroup来管理多个异步请求,待所有请求完成后再统一组装Place数组返回。
修改后的完整代码
public func findPlaces( query: String, completion: @escaping (Result<[Place], Error>) -> Void ) { let filter = GMSAutocompleteFilter() filter.types = ["geocode"] filter.countries = ["US"] client.findAutocompletePredictions( fromQuery: query, filter: filter, sessionToken: nil ) { results, error in guard let results = results, error == nil else { completion(.failure(PlacesError.failedToFind)) return } // 初始化调度组和结果存储数组 let dispatchGroup = DispatchGroup() var places: [Place] = [] var fetchErrors: [Error] = [] // 遍历所有预测结果,逐个发起详情请求 for result in results { dispatchGroup.enter() self.client.fetchPlace( fromPlaceID: result.placeID, placeFields: [.coordinate, .addressComponents], sessionToken: nil ) { googlePlace, error in defer { dispatchGroup.leave() } // 请求完成后必须调用leave if let error = error { fetchErrors.append(error) return } guard let googlePlace = googlePlace else { fetchErrors.append(PlacesError.failedToGetCoordinates) return } // 解析邮编 let zipCode = googlePlace.addressComponents? .first(where: { $0.types.contains("postal_code") })? .name ?? "" // 生成坐标对象 let coords = PlaceCoords(withCoords: googlePlace.coordinate) // 生成当前预测项对应的Place对象 let place = Place( name: result.attributedPrimaryText.string, identifier: result.placeID, detail: Utils.shared.removeCountryFromPlace(string: result.attributedFullText.string), coords: coords, zipcode: zipCode ) places.append(place) } } // 所有请求完成后统一处理结果 dispatchGroup.notify(queue: .main) { // 错误策略1:只要有一个请求失败就返回错误 if !fetchErrors.isEmpty { completion(.failure(fetchErrors.first ?? PlacesError.failedToGetCoordinates)) return } // 错误策略2:忽略失败的请求,仅返回成功获取的Place数组 // completion(.success(places)) completion(.success(places)) } } } // 补充错误枚举(如果之前未定义) enum PlacesError: Error { case failedToFind case failedToGetCoordinates }
关键改动说明
- 用
DispatchGroup跟踪所有fetchPlace请求的生命周期,确保所有请求完成后再组装结果 - 遍历每个自动补全预测结果,为每个结果单独发起详情请求,避免复用单个结果的坐标/邮编
- 维护错误数组,可灵活选择错误处理逻辑(全部失败才返回/忽略失败项)
- 通过
defer确保每个请求完成后调用dispatchGroup.leave(),防止调度组永久等待
注意事项
- 注意Google Places API的调用配额,批量请求会消耗更多配额,建议结合session token优化请求
- 可根据业务需求调整错误处理策略,比如允许部分失败仅返回成功的Place对象
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

