1+ import Foundation
2+
13typealias JSONDictionary = [ String : Any ]
24
35/// Indicates that an error occurred in MapboxGeocoder.
@@ -170,17 +172,22 @@ open class Geocoder: NSObject {
170172 - parameter completionHandler: The closure (block) to call with the resulting placemarks. This closure is executed on the application’s main thread.
171173 - returns: The data task used to perform the HTTP request. If, while waiting for the completion handler to execute, you no longer want the resulting placemarks, cancel this task.
172174 */
175+
176+ @discardableResult
173177 @objc ( geocodeWithOptions: completionHandler: )
174178 open func geocode( _ options: GeocodeOptions , completionHandler: @escaping CompletionHandler ) -> URLSessionDataTask {
175179 let url = urlForGeocoding ( options)
176- let task = dataTaskWithURL ( url, completionHandler: { ( json) in
177- let featureCollection = json as! JSONDictionary
178- assert ( featureCollection [ " type " ] as? String == " FeatureCollection " )
179- let features = featureCollection [ " features " ] as! [ JSONDictionary ]
180- let attribution = featureCollection [ " attribution " ] as? String
181-
182- let placemarks = features. flatMap { GeocodedPlacemark ( featureJSON: $0) }
183- completionHandler ( placemarks, attribution, nil )
180+
181+ let task = dataTaskWithURL ( url, completionHandler: { ( data) in
182+ guard let data = data else { return }
183+ let decoder = JSONDecoder ( )
184+ do {
185+ let result = try decoder. decode ( GeocodeResult . self, from: data)
186+ assert ( result. type == " FeatureCollection " )
187+ completionHandler ( result. placemarks, result. attribution, nil )
188+ } catch {
189+ completionHandler ( nil , nil , error as NSError )
190+ }
184191 } ) { ( error) in
185192 completionHandler ( nil , nil , error)
186193 }
@@ -201,15 +208,32 @@ open class Geocoder: NSObject {
201208 */
202209 open func batchGeocode< T: GeocodeOptions > ( _ options: T , completionHandler: @escaping BatchCompletionHandler ) -> URLSessionDataTask where T: BatchGeocodeOptions {
203210 let url = urlForGeocoding ( options)
204- let task = dataTaskWithURL ( url, completionHandler: { ( json) in
205- let featureCollections = json as! [ JSONDictionary ]
206- let placemarksByQuery = featureCollections. map { ( featureCollection) -> [ GeocodedPlacemark ] in
207- assert ( featureCollection [ " type " ] as? String == " FeatureCollection " )
208- let features = featureCollection [ " features " ] as! [ JSONDictionary ]
209- return features. flatMap { GeocodedPlacemark ( featureJSON: $0) }
210- }
211- let attributionsByQuery = featureCollections. map { $0 [ " attribution " ] as! String }
212- completionHandler ( placemarksByQuery, attributionsByQuery, nil )
211+
212+ // TODO: Migrate to Codable
213+
214+ // let task = dataTaskWithURL(url, completionHandler: { (json) in
215+ // let featureCollections = json as! [JSONDictionary]
216+ // let placemarksByQuery = featureCollections.map { (featureCollection) -> [GeocodedPlacemark] in
217+ // assert(featureCollection["type"] as? String == "FeatureCollection")
218+ // let features = featureCollection["features"] as! [JSONDictionary]
219+ // return features.flatMap { GeocodedPlacemark(featureJSON: $0) }
220+ // }
221+ // let attributionsByQuery = featureCollections.map { $0["attribution"] as! String }
222+ // completionHandler(placemarksByQuery, attributionsByQuery, nil)
223+ // }) { (error) in
224+ // completionHandler(nil, nil, error)
225+ // }
226+
227+ let task = dataTaskWithURL ( url, completionHandler: { ( data) in
228+ // let featureCollections = data as! [JSONDictionary]
229+ // let placemarksByQuery = featureCollections.map { (featureCollection) -> [GeocodedPlacemark] in
230+ // assert(featureCollection["type"] as? String == "FeatureCollection")
231+ // let features = featureCollection["features"] as! [JSONDictionary]
232+ // return features.flatMap { GeocodedPlacemark(featureJSON: $0) }
233+ // }
234+ // let attributionsByQuery = featureCollections.map { $0["attribution"] as! String }
235+
236+
213237 } ) { ( error) in
214238 completionHandler ( nil , nil , error)
215239 }
@@ -226,30 +250,23 @@ open class Geocoder: NSObject {
226250 - returns: The data task for the URL.
227251 - postcondition: The caller must resume the returned task.
228252 */
229- fileprivate func dataTaskWithURL( _ url: URL , completionHandler: @escaping ( _ json : Any ) -> Void , errorHandler: @escaping ( _ error: NSError ) -> Void ) -> URLSessionDataTask {
253+ fileprivate func dataTaskWithURL( _ url: URL , completionHandler: @escaping ( _ data : Data ? ) -> Void , errorHandler: @escaping ( _ error: NSError ) -> Void ) -> URLSessionDataTask {
230254 var request = URLRequest ( url: url)
231255 request. setValue ( userAgent, forHTTPHeaderField: " User-Agent " )
232256 return URLSession . shared. dataTask ( with: request) { ( data, response, error) in
233- var json : JSONDictionary = [ : ]
234- if let data = data, let mimeType = response? . mimeType, mimeType == " application/json " || mimeType == " application/vnd.geo+json " {
235- do {
236- json = try JSONSerialization . jsonObject ( with: data, options: [ ] ) as! JSONDictionary
237- } catch {
238- assert ( false , " Invalid data " )
239- }
240- }
241-
242- let apiMessage = json [ " message " ] as? String
243- guard data != nil && error == nil && apiMessage == nil else {
244- let apiError = Geocoder . descriptiveError ( json, response: response, underlyingError: error as NSError ? )
245- DispatchQueue . main. async {
246- errorHandler ( apiError)
247- }
248- return
249- }
257+
258+ // TODO: Migrate result to Codable
259+ // let apiMessage = json["message"] as? String
260+ // guard data != nil && error == nil && apiMessage == nil else {
261+ // let apiError = Geocoder.descriptiveError(json, response: response, underlyingError: error as NSError?)
262+ // DispatchQueue.main.async {
263+ // errorHandler(apiError)
264+ // }
265+ // return
266+ // }
250267
251268 DispatchQueue . main. async {
252- completionHandler ( json )
269+ completionHandler ( data )
253270 }
254271 }
255272 }
0 commit comments