Swift 3解析Google Places JSON时CLLocationCoordinate2D坐标异常
解决Google Places iOS API解析坐标为(0.0, 0.0)的问题
嘿,我一眼就发现问题所在啦!你解析坐标的代码之所以没生效,是因为对Google Places API返回的geometry结构理解错了——它是单个字典,不是字典数组,但你把它转成了[JSONDictionary]类型,导致那段解析坐标的代码块根本没有执行,所以坐标一直是默认的CLLocationCoordinate2D(latitude: 0.0, longitude: 0.0)。
具体错误点
在你的代码中,这段判断是核心错误:
if let geometry = gym["geometry"] as? [JSONDictionary] { // 错误:geometry不是数组类型 for result in geometry { if let locations = result["location"] as? [JSONDictionary] { // 同样错误:location也不是数组 for location in locations { // ... 解析lat和lng的逻辑 } } } }
根据Google Places API的返回格式,geometry是一个包含location字段的字典,而location又是一个包含lat(浮点数)和lng(浮点数)的字典,完全不需要循环遍历数组。
修正后的完整解析代码
我不仅修正了坐标解析的问题,还优化了强制解包的风险(避免API字段缺失导致崩溃),同时补上了你遗漏的数组初始化逻辑:
func parseJsonData(data: NSData) -> [GymGooglePlace] { var gymGooglePlaces = [GymGooglePlace]() // 必须初始化返回数组 do { typealias JSONDictionary = [String:Any] if let parsedData = try JSONSerialization.jsonObject(with: data as Data) as? JSONDictionary, let gyms = parsedData["results"] as? [JSONDictionary] { for gym in gyms { var coordinate = CLLocationCoordinate2D() // 正确解析geometry和location(无多余循环) if let geometry = gym["geometry"] as? JSONDictionary, let location = geometry["location"] as? JSONDictionary, let lat = location["lat"] as? CLLocationDegrees, let lng = location["lng"] as? CLLocationDegrees { coordinate.latitude = lat coordinate.longitude = lng } // 优化photos解析,避免强制解包 var maxWidth: Int? var photoReference: String? if let photos = gym["photos"] as? [JSONDictionary], let firstPhoto = photos.first { maxWidth = firstPhoto["width"] as? Int photoReference = firstPhoto["photo_reference"] as? String } // 安全拼接photoURL(避免空值崩溃) if let maxWidth = maxWidth, let photoReference = photoReference { let photoURL = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=\(maxWidth)&photoreference=\(photoReference)&key=\(googleAPIKey)" print(photoURL) } print(coordinate) print("spacespacespacespacespacespacespacespacespace") // 记得创建GymGooglePlace实例并添加到返回数组 // let gymPlace = GymGooglePlace(coordinate: coordinate, photoURL: photoURL, ...) // gymGooglePlaces.append(gymPlace) } } } catch { print(error) } return gymGooglePlaces }
额外注意事项
- 你原来的代码没有初始化
gymGooglePlaces数组,也没有将解析后的对象添加进去,这会导致返回空数组,一定要补上这部分逻辑。 - 尽量避免使用强制解包(
!),一旦API返回的字段缺失或类型不匹配,App会直接崩溃,用if let的可选绑定更安全。 - 如果
photos数组为空,maxWidth和photoReference会是nil,此时不要拼接photoURL,上面的代码已经处理了这种边界情况。
内容的提问来源于stack exchange,提问作者Annabelle Sykes
相关产品推荐
相关产品推荐

