正如@iOS所建议的那样,我也会发布我的答案,向您展示如何使用Codable和Alamofire/Moya来完成它。
为此,您需要重新设计GoogleMaps响应实体,如下所示:
struct GMSDirectionsResponse: Codable {
let routes: [GMSRoute]
let status: String
}
struct GMSRoute: Codable {
struct Bounds: Codable {
}
struct Leg: Codable {
}
struct Step: Codable {
}
struct OverviewPolyline: Codable {
let points: String
}
let bounds: Bounds?
let legs: [Leg]?
let overview_polyline: OverviewPolyline?
let summary: String?
}
你可以看到一个响应对象由一组路线和一个状态字符串(例如"OK"
)组成的数组。每条路线都有一些属性,包括overview_polyline
字段。为了能够让一个JSONDecoder
将该对象解码,你还需要对该类进行建模(它只包含一个用于键points
的字符串值)。
现在,如果你只需要overview_polyline
,完全可以省略所有其他不必要的属性和结构,只要你仍然建模响应的分层结构即可(例如GMSDirectionsResponse > GMSRoute > OverviewPolyline > points
)。
现在你可以使用单行代码从正文数据中请求一个GMSDirectionsResponse
来请求一个JSONDecoder
!在我的项目中,我使用了Moya,但我相信你也可以使用URLSession
的data
对象。
let moya = MoyaProvider<YourGMSService>()
moya.request(.getDirections(origin: origin, destination: destination)) { (result) in
switch result {
case .success(let response):
if
(try? response.filterSuccessfulStatusCodes()) != nil,
let directions = try? JSONDecoder().decode(GMSDirectionsResponse.self, from: response.data)
{
NSLog("GET DIRECTIONS: Success")
NSLog("GoogleMaps Directions request finished with status %@", directions.status)
guard let encodedPath = directions.routes.first?.overview_polyline else { return }
DispatchQueue.main.async {
let path = GMSPath.init(fromEncodedPath: encodedPath.points)
let singleLine = GMSPolyline.init(path: path)
singleLine.strokeWidth = 6.0
singleLine.strokeColor = .blue
singleLine.map = mapView
}
return
}
NSLog("Could not parse JSON from Directions API Response:\n%@", response.debugDescription)
case .failure(let error):
NSLog(error.localizedDescription)
}
NSLog("GET DIRECTIONS: Failed")
}
这段代码看起来可能很长,但它非常方便,可以避免你在处理 JSON 下标成员和大量的 []
括号时出现混乱。
如果您有任何问题,我很乐意帮助!