@@ -10,120 +10,79 @@ public func ==(left: CLLocationCoordinate2D, right: CLLocationCoordinate2D) -> B
1010 return ( left. latitude == right. latitude && left. longitude == right. longitude)
1111}
1212
13- // MARK: - Geocoder
13+ public let MBGeocoderErrorDomain = " MBGeocoderErrorDomain "
1414
15- public class MBGeocoder : NSObject ,
16- NSURLConnectionDelegate ,
17- NSURLConnectionDataDelegate {
15+ public class MBGeocoder : NSObject {
1816
19- // MARK: - Setup
20-
21- private let accessToken : NSString
17+ private let configuration : MBGeocoderConfiguration
2218
23- public init ( accessToken: NSString ) {
24- self . accessToken = accessToken
25- super. init ( )
19+ public init ( accessToken: String ) {
20+ configuration = MBGeocoderConfiguration ( accessToken)
2621 }
27-
28- private var connection : NSURLConnection ?
29- private var completionHandler : MBGeocodeCompletionHandler ?
30- private var receivedData : NSMutableData ?
3122
32- private let MBGeocoderErrorDomain = " MBGeocoderErrorDomain "
33-
34- private enum MBGeocoderErrorCode : Int {
35- case ConnectionError = - 1000
36- case HTTPError = - 1001
37- case ParseError = - 1002
23+ private var task : NSURLSessionDataTask ?
24+
25+ private var errorForSimultaneousRequests : NSError {
26+ let userInfo = [
27+ NSLocalizedFailureReasonErrorKey: " Cannot geocode on an MBGeocoder object that is already geocoding. " ,
28+ ]
29+ return NSError ( domain: MBGeocoderErrorDomain, code: - 1 , userInfo: userInfo)
3830 }
3931
40- // MARK: - Public API
41-
4232 public var geocoding : Bool {
43- return ( self . connection != nil )
33+ return task ? . state == . Running
4434 }
4535
4636 public func reverseGeocodeLocation( location: CLLocation , completionHandler: MBGeocodeCompletionHandler ) {
47- if !self . geocoding {
48- self . completionHandler = completionHandler
49- let requestString = String ( format: " https://api.mapbox.com/geocoding/v5/mapbox.places/%.5f,%.5f.json?access_token=%@ " ,
50- round ( location. coordinate. longitude * 1e5 ) / 1e5 ,
51- round ( location. coordinate. latitude * 1e5 ) / 1e5 , accessToken)
52- let request = NSURLRequest ( URL: NSURL ( string: requestString) !)
53- self . connection = NSURLConnection ( request: request, delegate: self )
37+ guard !geocoding else {
38+ completionHandler ( nil , errorForSimultaneousRequests)
39+ return
5440 }
41+
42+ let query = String ( format: " %.5f,%.5f " , location. coordinate. longitude, location. coordinate. latitude)
43+ let router = MBGeocoderRouter . V5 ( configuration, false , query, nil , nil , nil , nil )
44+ task = taskWithRouter ( router, completionHandler: completionHandler)
5545 }
5646
5747// public func geocodeAddressDictionary(addressDictionary: [NSObject : AnyObject],
5848// completionHandler: MBGeocodeCompletionHandler)
5949
60- public func geocodeAddressString( addressString: String , proximity: CLLocationCoordinate2D ? = nil , completionHandler: MBGeocodeCompletionHandler ) {
61- if !self . geocoding {
62- self . completionHandler = completionHandler
63- var requestString = " https://api.mapbox.com/geocoding/v5/mapbox.places/ " +
64- addressString. stringByAddingPercentEncodingWithAllowedCharacters ( NSCharacterSet . URLPathAllowedCharacterSet ( ) ) ! +
65- " .json?access_token= \( accessToken) "
66- if let proximityCoordinate = proximity {
67- requestString += String ( format: " &proximity=%.3f,%.3f " ,
68- round ( proximityCoordinate. longitude * 1e3 ) / 1e3 ,
69- round ( proximityCoordinate. latitude * 1e3 ) / 1e3 )
70- }
71- let request = NSURLRequest ( URL: NSURL ( string: requestString) !)
72- self . connection = NSURLConnection ( request: request, delegate: self )
50+ public func geocodeAddressString( addressString: String , nearLocation focusLocation: CLLocation ? = nil , inCountries ISOCountryCodes: [ String ] ? = nil , completionHandler: MBGeocodeCompletionHandler ) {
51+ guard !geocoding else {
52+ completionHandler ( nil , errorForSimultaneousRequests)
53+ return
7354 }
55+
56+ let router = MBGeocoderRouter . V5 ( configuration, false , addressString, ISOCountryCodes, focusLocation? . coordinate, nil , nil )
57+ task = taskWithRouter ( router, completionHandler: completionHandler)
7458 }
7559
7660// public func geocodeAddressString(addressString: String, inRegion region: CLRegion, completionHandler: MBGeocodeCompletionHandler)
77-
78- public func cancelGeocode( ) {
79- self . connection? . cancel ( )
80- self . connection = nil
81- }
8261
83- // MARK: - NSURLConnection Delegates
84-
85- public func connection( connection: NSURLConnection , didFailWithError error: NSError ) {
86- self . connection = nil
87- self . completionHandler ? ( nil , NSError ( domain: MBGeocoderErrorDomain,
88- code: MBGeocoderErrorCode . ConnectionError. rawValue,
89- userInfo: error. userInfo) )
90- }
91-
92- public func connection( connection: NSURLConnection , didReceiveResponse response: NSURLResponse ) {
93- let statusCode = ( response as! NSHTTPURLResponse ) . statusCode
94- if statusCode != 200 {
95- self . connection? . cancel ( )
96- self . connection = nil
97- self . completionHandler ? ( nil , NSError ( domain: MBGeocoderErrorDomain,
98- code: MBGeocoderErrorCode . HTTPError. rawValue,
99- userInfo: [ NSLocalizedDescriptionKey: " Received HTTP status code \( statusCode) " ] ) )
100- } else {
101- self . receivedData = NSMutableData ( )
102- }
103- }
104-
105- public func connection( connection: NSURLConnection , didReceiveData data: NSData ) {
106- self . receivedData!. appendData ( data)
107- }
108-
109- public func connectionDidFinishLoading( connection: NSURLConnection ) {
110- if let response = ( try ? NSJSONSerialization . JSONObjectWithData ( self . receivedData!, options: [ ] ) ) as? JSON {
111- if let features = response [ " features " ] as? [ JSON ] {
112- var results : [ MBPlacemark ] = [ ]
113- for feature in features {
114- if let placemark = MBPlacemark ( featureJSON: feature) {
115- results. append ( placemark)
116- }
62+ private func taskWithRouter( router: MBGeocoderRouter , completionHandler completion: MBGeocodeCompletionHandler ) -> NSURLSessionDataTask ? {
63+ return router. loadJSON ( JSON . self) { [ weak self] ( json, error) in
64+ guard let dataTaskSelf = self where dataTaskSelf. task? . state == . Completed
65+ else {
66+ return
67+ }
68+
69+ guard error == nil && json != nil else {
70+ dispatch_sync ( dispatch_get_main_queue ( ) ) {
71+ completion ( nil , error as? NSError )
11772 }
118- self . completionHandler ? ( results, nil )
119- } else {
120- self . completionHandler ? ( [ ] , nil )
73+ return
74+ }
75+
76+ let features = json![ " features " ] as! [ JSON ]
77+ let placemarks = features. flatMap { MBPlacemark ( featureJSON: $0) }
78+
79+ dispatch_sync ( dispatch_get_main_queue ( ) ) {
80+ completion ( placemarks, error as? NSError )
12181 }
122- } else {
123- self . completionHandler ? ( nil , NSError ( domain: MBGeocoderErrorDomain,
124- code: MBGeocoderErrorCode . ParseError. rawValue,
125- userInfo: [ NSLocalizedDescriptionKey: " Unable to parse results " ] ) )
12682 }
12783 }
12884
85+ public func cancelGeocode( ) {
86+ task? . cancel ( )
87+ }
12988}
0 commit comments