diff --git a/README.md b/README.md index 710ef03..2b90faf 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ SPGooglePlacesAutocomplete requires a deployment target >= iOS 5.0. * SPGooglePlacesAutocompleteQuery.h/.m * SPGooglePlacesPlaceDetailQuery.h/.m * SPGooglePlacesAutocompletePlace.h/.m + * SPGooglePlacesAutocompletePlaceDetails.h/.m 3. (Optional) If you would like to utilize the provided sample view controller for searching and mapping Places, link your project against the MapKit framework and copy the following files to your project: * SPGooglePlacesAutocompleteViewController.h/.m/.xib * locateButton(@2x).png diff --git a/SPGooglePlacesAutocomplete.xcodeproj/project.pbxproj b/SPGooglePlacesAutocomplete.xcodeproj/project.pbxproj index 1a2e66f..d7281c7 100644 --- a/SPGooglePlacesAutocomplete.xcodeproj/project.pbxproj +++ b/SPGooglePlacesAutocomplete.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ 9C4A63AE15B6C0DB00E15FBA /* locateButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C4A63AC15B6C0DB00E15FBA /* locateButton.png */; }; 9C4A63AF15B6C0DB00E15FBA /* locateButton@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C4A63AD15B6C0DB00E15FBA /* locateButton@2x.png */; }; 9C4A63B215B73EA300E15FBA /* SPGooglePlacesPlaceDetailQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C4A63B115B73EA200E15FBA /* SPGooglePlacesPlaceDetailQuery.m */; }; + B9577BD3178123BF00BF7468 /* SPGooglePlacesAutocompletePlaceDetails.m in Sources */ = {isa = PBXBuildFile; fileRef = B9577BD2178123BF00BF7468 /* SPGooglePlacesAutocompletePlaceDetails.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -55,6 +56,8 @@ 9C4A63AD15B6C0DB00E15FBA /* locateButton@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "locateButton@2x.png"; sourceTree = ""; }; 9C4A63B015B73EA200E15FBA /* SPGooglePlacesPlaceDetailQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPGooglePlacesPlaceDetailQuery.h; sourceTree = ""; }; 9C4A63B115B73EA200E15FBA /* SPGooglePlacesPlaceDetailQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPGooglePlacesPlaceDetailQuery.m; sourceTree = ""; }; + B9577BD1178123BF00BF7468 /* SPGooglePlacesAutocompletePlaceDetails.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPGooglePlacesAutocompletePlaceDetails.h; sourceTree = ""; }; + B9577BD2178123BF00BF7468 /* SPGooglePlacesAutocompletePlaceDetails.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPGooglePlacesAutocompletePlaceDetails.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -115,6 +118,8 @@ 9C4A63B115B73EA200E15FBA /* SPGooglePlacesPlaceDetailQuery.m */, 9C4A633D15B64FA400E15FBA /* SPGooglePlacesAutocompletePlace.h */, 9C4A633E15B64FA400E15FBA /* SPGooglePlacesAutocompletePlace.m */, + B9577BD1178123BF00BF7468 /* SPGooglePlacesAutocompletePlaceDetails.h */, + B9577BD2178123BF00BF7468 /* SPGooglePlacesAutocompletePlaceDetails.m */, 9C4A634415B6950B00E15FBA /* SPGooglePlacesAutocompleteViewController.h */, 9C4A634515B6950B00E15FBA /* SPGooglePlacesAutocompleteViewController.m */, 9C4A634615B6950B00E15FBA /* SPGooglePlacesAutocompleteViewController.xib */, @@ -220,6 +225,7 @@ 9C4A634715B6950C00E15FBA /* SPGooglePlacesAutocompleteViewController.m in Sources */, 9C4A63A015B6A4FB00E15FBA /* SPGooglePlacesAutocompleteUtilities.m in Sources */, 9C4A63B215B73EA300E15FBA /* SPGooglePlacesPlaceDetailQuery.m in Sources */, + B9577BD3178123BF00BF7468 /* SPGooglePlacesAutocompletePlaceDetails.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -325,6 +331,7 @@ 9C4A633715B64A3F00E15FBA /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.h b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.h index 799b6dd..e35a9af 100644 --- a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.h +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.h @@ -41,4 +41,9 @@ */ - (void)resolveToPlacemark:(SPGooglePlacesPlacemarkResultBlock)block; +/*! + Fetch Google Place Details. + */ +- (void)fetchPlaceDetails:(SPGooglePlacesPlaceDetailResultBlock)block; + @end diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.m b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.m index bf8e434..41c1848 100644 --- a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.m +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.m @@ -7,6 +7,7 @@ // #import "SPGooglePlacesAutocompletePlace.h" +#import "SPGooglePlacesAutocompletePlaceDetails.h" #import "SPGooglePlacesPlaceDetailQuery.h" @interface SPGooglePlacesAutocompletePlace() @@ -41,14 +42,19 @@ - (CLGeocoder *)geocoder { return geocoder; } -- (void)resolveEstablishmentPlaceToPlacemark:(SPGooglePlacesPlacemarkResultBlock)block { +- (void)fetchPlaceDetails:(SPGooglePlacesPlaceDetailResultBlock)block { SPGooglePlacesPlaceDetailQuery *query = [SPGooglePlacesPlaceDetailQuery query]; query.reference = self.reference; - [query fetchPlaceDetail:^(NSDictionary *placeDictionary, NSError *error) { + [query fetchPlaceDetail:block]; +} + +- (void)resolveEstablishmentPlaceToPlacemark:(SPGooglePlacesPlacemarkResultBlock)block { + + [self fetchPlaceDetails:^(SPGooglePlacesAutocompletePlaceDetails *placeDetails, NSError *error) { if (error) { block(nil, nil, error); } else { - NSString *addressString = [placeDictionary objectForKey:@"formatted_address"]; + NSString *addressString = placeDetails.formattedAddress; [[self geocoder] geocodeAddressString:addressString completionHandler:^(NSArray *placemarks, NSError *error) { if (error) { block(nil, nil, error); diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlaceDetails.h b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlaceDetails.h new file mode 100644 index 0000000..193b137 --- /dev/null +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlaceDetails.h @@ -0,0 +1,24 @@ +// +// SPGooglePlacesAutocompletePlaceDetails.h +// SPGooglePlacesAutocomplete +// +// Created by Michael Vosseller on 6/30/13. +// Copyright (c) 2013 Stephen Poletto. All rights reserved. +// + +#import + +@interface SPGooglePlacesAutocompletePlaceDetails : NSObject { + NSDictionary *dictionary; +} + ++ (SPGooglePlacesAutocompletePlaceDetails *)placeDetailsFromDictionary:(NSDictionary *)placeDetailsDictionary; + +@property (nonatomic, readonly) NSDictionary *dictionary; +@property (nonatomic, readonly) NSString *name; +@property (nonatomic, readonly) NSString *reference; +@property (nonatomic, readonly) NSString *identifier; +@property (nonatomic, readonly) NSString *formattedAddress; +@property (nonatomic, readonly) CLLocation *location; + +@end diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlaceDetails.m b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlaceDetails.m new file mode 100644 index 0000000..95cad85 --- /dev/null +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlaceDetails.m @@ -0,0 +1,77 @@ +// +// SPGooglePlacesAutocompletePlaceDetails.m +// SPGooglePlacesAutocomplete +// +// Created by Michael Vosseller on 6/30/13. +// Copyright (c) 2013 Stephen Poletto. All rights reserved. +// + +#import "SPGooglePlacesAutocompletePlaceDetails.h" + +@interface SPGooglePlacesAutocompletePlaceDetails() +@property (nonatomic, retain, readwrite) NSDictionary *dictionary; +@end + + +@implementation SPGooglePlacesAutocompletePlaceDetails + +@synthesize dictionary; + ++ (SPGooglePlacesAutocompletePlaceDetails *)placeDetailsFromDictionary:(NSDictionary *)placeDetailsDictionary { + SPGooglePlacesAutocompletePlaceDetails *placeDetails = [[[SPGooglePlacesAutocompletePlaceDetails alloc] init] autorelease]; + placeDetails.dictionary = placeDetailsDictionary; + return placeDetails; +} + +- (void) dealloc { + [super dealloc]; + [dictionary release]; +} + +- (NSString *) description { + return [NSString stringWithFormat:@"Name: %@, Reference: %@, Identifier: %@, Location: %@", + self.name, self.reference, self.identifier, self.location]; +} + +- (NSString *) name { + return self.dictionary[@"name"]; +} + +- (NSString *) reference { + return self.dictionary[@"reference"]; +} + +- (NSString *) identifier { + return self.dictionary[@"id"]; +} + +- (NSString*) formattedAddress { + return self.dictionary[@"formatted_address"]; +} + +- (CLLocation*) location { + + CLLocation *location = nil; + + NSDictionary *locationDictionary = [self locationDictionary]; + NSNumber *latitudeAsNumber = locationDictionary[@"lat"]; + NSNumber *lonitudeAsNumber = locationDictionary[@"lng"]; + + if (latitudeAsNumber && lonitudeAsNumber) { + CLLocationDegrees latitudeDegrees = [latitudeAsNumber doubleValue]; + CLLocationDegrees longitudeDegrees = [lonitudeAsNumber doubleValue]; + location = [[[CLLocation alloc] initWithLatitude:latitudeDegrees longitude:longitudeDegrees] autorelease]; + } + + return location; +} + +- (NSDictionary*) geometryDictionary { + return self.dictionary[@"geometry"]; +} + +- (NSDictionary*) locationDictionary { + return [self geometryDictionary][@"location"]; +} + +@end diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.h b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.h index 6684fc3..1b4869a 100644 --- a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.h +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.h @@ -70,5 +70,11 @@ */ @property (nonatomic) SPGooglePlacesAutocompletePlaceType types; + +/*! + Country code of the country to which results should be restricted to. Use "fr" for example to restrict your results to places within France. Must be a two character, ISO 3166-1 Alpha-2 compatible country code + */ +@property (nonatomic, retain) NSString *countryCode; + @end diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.m b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.m index 2faf0f1..44e3de4 100644 --- a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.m +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.m @@ -15,7 +15,7 @@ @interface SPGooglePlacesAutocompleteQuery() @implementation SPGooglePlacesAutocompleteQuery -@synthesize input, sensor, key, offset, location, radius, language, types, resultBlock; +@synthesize input, sensor, key, offset, location, radius, language, types, countryCode, resultBlock; + (SPGooglePlacesAutocompleteQuery *)query { return [[[self alloc] init] autorelease]; @@ -45,6 +45,7 @@ - (void)dealloc { [input release]; [key release]; [language release]; + [countryCode release]; [super dealloc]; } @@ -67,6 +68,10 @@ - (NSString *)googleURLString { if (types != -1) { [url appendFormat:@"&types=%@", SPPlaceTypeStringForPlaceType(types)]; } + if (countryCode != nil) { + [url appendFormat:@"&components=country:%@", countryCode]; + } + return url; } diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.h b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.h index e10ab95..b2c7b4f 100644 --- a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.h +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.h @@ -9,6 +9,7 @@ #define kGoogleAPIKey @"YOUR_API_KEY" #define kGoogleAPINSErrorCode 42 +@class SPGooglePlacesAutocompletePlaceDetails; @class CLPlacemark; typedef enum { @@ -18,7 +19,7 @@ typedef enum { typedef void (^SPGooglePlacesPlacemarkResultBlock)(CLPlacemark *placemark, NSString *addressString, NSError *error); typedef void (^SPGooglePlacesAutocompleteResultBlock)(NSArray *places, NSError *error); -typedef void (^SPGooglePlacesPlaceDetailResultBlock)(NSDictionary *placeDictionary, NSError *error); +typedef void (^SPGooglePlacesPlaceDetailResultBlock)(SPGooglePlacesAutocompletePlaceDetails *placeDetails, NSError *error); extern SPGooglePlacesAutocompletePlaceType SPPlaceTypeFromDictionary(NSDictionary *placeDictionary); extern NSString *SPBooleanStringForBool(BOOL boolean); diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesPlaceDetailQuery.m b/SPGooglePlacesAutocomplete/SPGooglePlacesPlaceDetailQuery.m index 558dd9c..5241458 100644 --- a/SPGooglePlacesAutocomplete/SPGooglePlacesPlaceDetailQuery.m +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesPlaceDetailQuery.m @@ -7,6 +7,7 @@ // #import "SPGooglePlacesPlaceDetailQuery.h" +#import "SPGooglePlacesAutocompletePlaceDetails.h" @interface SPGooglePlacesPlaceDetailQuery() @property (nonatomic, copy, readwrite) SPGooglePlacesPlaceDetailResultBlock resultBlock; @@ -90,7 +91,8 @@ - (void)failWithError:(NSError *)error { - (void)succeedWithPlace:(NSDictionary *)placeDictionary { if (self.resultBlock != nil) { - self.resultBlock(placeDictionary, nil); + SPGooglePlacesAutocompletePlaceDetails *placeDetails = [SPGooglePlacesAutocompletePlaceDetails placeDetailsFromDictionary:placeDictionary]; + self.resultBlock(placeDetails, nil); } [self cleanup]; }