正如@iOS 所建议的,我还将发布我的答案,向您展示如何使用 Codable 和 Alamofire/Moya 来完成它。
为此,您必须改造 GoogleMaps 响应实体,如下所示:
/// Struct for modelling a response from the Google Maps Directions API. This is the "root level"
struct GMSDirectionsResponse: Codable {
/// The suggested routes
let routes: [GMSRoute]
/// Status telling if request was okay
let status: String
}
/// Struct for modelling a Route suggested by GoogleMaps Directions API.
struct GMSRoute: Codable {
/// Represents an area in the map
struct Bounds: Codable {
// You can omit these structs for your case.
// Just to give an idea how it would look like if you model the entire response
// ...
}
struct Leg: Codable {
// ...
}
/// A single step of a route
struct Step: Codable {
// ...
}
/// Structure around the coded representation of the GMSPath
struct OverviewPolyline: Codable {
/// A coded representation of the GMSPath
let points: String
}
/// The bounds to show on the map to include the whole route
let bounds: Bounds?
/// All legs of this route, including the single steps
let legs: [Leg]?
/// The path to walk/drive/etc. this route
let overview_polyline: OverviewPolyline?
/// A textual summary of the most important roads to take
let summary: String?
}
您可以看到响应对象如何由路由数组和状态字符串组成(例如"OK")。每条路由又有几个属性,包括overview_polyline 字段。为了能够通过 JSONDecoder 解码该对象,您还需要对该类进行建模(它只包含键 points 的字符串值。
现在,如果您只需要 overview_polyline,则可以忽略所有其他不需要的属性和结构,只要您仍然对响应的层次结构进行建模(例如 GMSDirectionsResponse > GMSRoute > OverviewPolyline > points)。
您现在可以做的是让JSONDecoder 用一行代码从正文数据中解码GMSDirectionsResponse!在我的项目中,我使用了Moya,但我相信您也可以使用URLSession 的data 对象。
// let moya do request
let moya = MoyaProvider<YourGMSService>()
moya.request(.getDirections(origin: origin, destination: destination)) { (result) in
switch result {
case .success(let response):
// check if request was successful
if
// makes sure status is code is 2xx
(try? response.filterSuccessfulStatusCodes()) != nil,
// this line tries to decode a GMSDirectionsResponse object from response.data
let directions = try? JSONDecoder().decode(GMSDirectionsResponse.self, from: response.data)
{
// successful request, converted response to JSON Dictionary
NSLog("GET DIRECTIONS: Success")
// here we can check for the directions properites already!
NSLog("GoogleMaps Directions request finished with status %@", directions.status)
// check if we have at least one GMSRoute with an overview_polyline
guard let encodedPath = directions.routes.first?.overview_polyline else { return }
// now let's use the encoded path:
DispatchQueue.main.async {
let path = GMSPath.init(fromEncodedPath: encodedPath.points)
// continue as in other answers (Y)
let singleLine = GMSPolyline.init(path: path)
singleLine.strokeWidth = 6.0
singleLine.strokeColor = .blue
singleLine.map = mapView
}
return
}
// some error handling if we couldn't parse the data to a GMSDirectionsResponse object
NSLog("Could not parse JSON from Directions API Response:\n%@", response.debugDescription)
case .failure(let error):
// we had an error
NSLog(error.localizedDescription)
}
// log and complete with nil
NSLog("GET DIRECTIONS: Failed")
}
这可能看起来像一大堆代码,但它非常方便,它可以让您避免弄乱 JSON 下标成员和大量 [] 大括号。 ?
如果您有任何问题,我很乐意为您提供帮助!