diff --git a/Default-568h@2x.png b/Default-568h@2x.png new file mode 100644 index 0000000..0891b7a Binary files /dev/null and b/Default-568h@2x.png differ diff --git a/SPGooglePlacesAutocomplete.xcodeproj/project.pbxproj b/SPGooglePlacesAutocomplete.xcodeproj/project.pbxproj index 1a2e66f..716eec3 100644 --- a/SPGooglePlacesAutocomplete.xcodeproj/project.pbxproj +++ b/SPGooglePlacesAutocomplete.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 31CA0C591A14344C0082C552 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 31CA0C581A14344C0082C552 /* Default-568h@2x.png */; }; 9C4A632215B64A3F00E15FBA /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C4A632115B64A3F00E15FBA /* UIKit.framework */; }; 9C4A632415B64A3F00E15FBA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C4A632315B64A3F00E15FBA /* Foundation.framework */; }; 9C4A632615B64A3F00E15FBA /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C4A632515B64A3F00E15FBA /* CoreGraphics.framework */; }; @@ -28,6 +29,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 31CA0C581A14344C0082C552 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 9C4A631D15B64A3F00E15FBA /* SPGooglePlacesAutocomplete.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SPGooglePlacesAutocomplete.app; sourceTree = BUILT_PRODUCTS_DIR; }; 9C4A632115B64A3F00E15FBA /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 9C4A632315B64A3F00E15FBA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -76,6 +78,7 @@ 9C4A631215B64A3F00E15FBA = { isa = PBXGroup; children = ( + 31CA0C581A14344C0082C552 /* Default-568h@2x.png */, 9C4A632715B64A3F00E15FBA /* SPGooglePlacesAutocomplete */, 9C4A632015B64A3F00E15FBA /* Frameworks */, 9C4A631E15B64A3F00E15FBA /* Products */, @@ -172,7 +175,7 @@ 9C4A631415B64A3F00E15FBA /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0450; + LastUpgradeCheck = 0610; ORGANIZATIONNAME = "Stephen Poletto"; }; buildConfigurationList = 9C4A631715B64A3F00E15FBA /* Build configuration list for PBXProject "SPGooglePlacesAutocomplete" */; @@ -202,6 +205,7 @@ 9C4A63A615B6C01100E15FBA /* location.png in Resources */, 9C4A63A715B6C01100E15FBA /* location@2x.png in Resources */, 9C4A63AE15B6C0DB00E15FBA /* locateButton.png in Resources */, + 31CA0C591A14344C0082C552 /* Default-568h@2x.png in Resources */, 9C4A63AF15B6C0DB00E15FBA /* locateButton@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -258,6 +262,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 6.0; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; @@ -285,6 +290,7 @@ 9C4A633615B64A3F00E15FBA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "SPGooglePlacesAutocomplete/SPGooglePlacesAutocomplete-Prefix.pch"; INFOPLIST_FILE = "SPGooglePlacesAutocomplete/SPGooglePlacesAutocomplete-Info.plist"; @@ -297,6 +303,7 @@ 9C4A633715B64A3F00E15FBA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_ARC = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "SPGooglePlacesAutocomplete/SPGooglePlacesAutocomplete-Prefix.pch"; INFOPLIST_FILE = "SPGooglePlacesAutocomplete/SPGooglePlacesAutocomplete-Info.plist"; @@ -325,6 +332,7 @@ 9C4A633715B64A3F00E15FBA /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..09df3f9 --- /dev/null +++ b/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/xcshareddata/SPGooglePlacesAutocomplete.xccheckout b/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/xcshareddata/SPGooglePlacesAutocomplete.xccheckout new file mode 100644 index 0000000..d9a769f --- /dev/null +++ b/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/xcshareddata/SPGooglePlacesAutocomplete.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 88E4F410-3060-491C-8448-75312C7744AE + IDESourceControlProjectName + SPGooglePlacesAutocomplete + IDESourceControlProjectOriginsDictionary + + 3BAC43AA9CAA0E6DDD799DA562082A4246A801B0 + github.com:vertigo/SPGooglePlacesAutocomplete.git + + IDESourceControlProjectPath + SPGooglePlacesAutocomplete.xcodeproj + IDESourceControlProjectRelativeInstallPathDictionary + + 3BAC43AA9CAA0E6DDD799DA562082A4246A801B0 + ../.. + + IDESourceControlProjectURL + github.com:vertigo/SPGooglePlacesAutocomplete.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + 3BAC43AA9CAA0E6DDD799DA562082A4246A801B0 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + 3BAC43AA9CAA0E6DDD799DA562082A4246A801B0 + IDESourceControlWCCName + SPGooglePlacesAutocomplete + + + + diff --git a/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/xcuserdata/dherberger.xcuserdatad/UserInterfaceState.xcuserstate b/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/xcuserdata/dherberger.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..8b44429 Binary files /dev/null and b/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/xcuserdata/dherberger.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/xcuserdata/dherberger.xcuserdatad/WorkspaceSettings.xcsettings b/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/xcuserdata/dherberger.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..659c876 --- /dev/null +++ b/SPGooglePlacesAutocomplete.xcodeproj/project.xcworkspace/xcuserdata/dherberger.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,10 @@ + + + + + HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges + + SnapshotAutomaticallyBeforeSignificantChanges + + + diff --git a/SPGooglePlacesAutocomplete.xcodeproj/xcuserdata/dherberger.xcuserdatad/xcschemes/SPGooglePlacesAutocomplete.xcscheme b/SPGooglePlacesAutocomplete.xcodeproj/xcuserdata/dherberger.xcuserdatad/xcschemes/SPGooglePlacesAutocomplete.xcscheme new file mode 100644 index 0000000..6405a57 --- /dev/null +++ b/SPGooglePlacesAutocomplete.xcodeproj/xcuserdata/dherberger.xcuserdatad/xcschemes/SPGooglePlacesAutocomplete.xcscheme @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SPGooglePlacesAutocomplete.xcodeproj/xcuserdata/dherberger.xcuserdatad/xcschemes/xcschememanagement.plist b/SPGooglePlacesAutocomplete.xcodeproj/xcuserdata/dherberger.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..58677dc --- /dev/null +++ b/SPGooglePlacesAutocomplete.xcodeproj/xcuserdata/dherberger.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + SPGooglePlacesAutocomplete.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 9C4A631C15B64A3F00E15FBA + + primary + + + + + diff --git a/SPGooglePlacesAutocomplete/AppDelegate.m b/SPGooglePlacesAutocomplete/AppDelegate.m index dd1f14a..48362af 100644 --- a/SPGooglePlacesAutocomplete/AppDelegate.m +++ b/SPGooglePlacesAutocomplete/AppDelegate.m @@ -14,18 +14,13 @@ @implementation AppDelegate @synthesize window; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - SPGooglePlacesAutocompleteViewController *viewController = [[[SPGooglePlacesAutocompleteViewController alloc] init] autorelease]; + SPGooglePlacesAutocompleteViewController *viewController = [[SPGooglePlacesAutocompleteViewController alloc] init]; self.window.rootViewController = viewController; [self.window makeKeyAndVisible]; return YES; } -- (void)dealloc { - [window release]; - [super dealloc]; -} - @end diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.m b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.m index bf8e434..6d0e1b2 100644 --- a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.m +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompletePlace.m @@ -9,6 +9,8 @@ #import "SPGooglePlacesAutocompletePlace.h" #import "SPGooglePlacesPlaceDetailQuery.h" +#import + @interface SPGooglePlacesAutocompletePlace() @property (nonatomic, retain, readwrite) NSString *name; @property (nonatomic, retain, readwrite) NSString *reference; @@ -21,10 +23,10 @@ @implementation SPGooglePlacesAutocompletePlace @synthesize name, reference, identifier, type; + (SPGooglePlacesAutocompletePlace *)placeFromDictionary:(NSDictionary *)placeDictionary { - SPGooglePlacesAutocompletePlace *place = [[[self alloc] init] autorelease]; + SPGooglePlacesAutocompletePlace *place = [[self alloc] init]; place.name = [placeDictionary objectForKey:@"description"]; place.reference = [placeDictionary objectForKey:@"reference"]; - place.identifier = [placeDictionary objectForKey:@"id"]; + place.identifier = [placeDictionary objectForKey:@"place_id"]; place.type = SPPlaceTypeFromDictionary(placeDictionary); return place; } @@ -41,22 +43,60 @@ - (CLGeocoder *)geocoder { return geocoder; } -- (void)resolveEstablishmentPlaceToPlacemark:(SPGooglePlacesPlacemarkResultBlock)block { +- (void)resolveReferenceIdentifierToPlacemark:(SPGooglePlacesPlacemarkResultBlock)block { SPGooglePlacesPlaceDetailQuery *query = [SPGooglePlacesPlaceDetailQuery query]; - query.reference = self.reference; + query.placeIdentifier = self.identifier; [query fetchPlaceDetail:^(NSDictionary *placeDictionary, NSError *error) { if (error) { block(nil, nil, error); } else { - NSString *addressString = [placeDictionary objectForKey:@"formatted_address"]; - [[self geocoder] geocodeAddressString:addressString completionHandler:^(NSArray *placemarks, NSError *error) { - if (error) { - block(nil, nil, error); + if (placeDictionary) { + NSString *placeAddress = [placeDictionary objectForKey:@"formatted_address"]; + NSDictionary *placeGeometryDictionary = [placeDictionary objectForKey:@"geometry"]; + NSDictionary *placeLocationDictionary = nil; + NSNumber *latitude = nil; + NSNumber *longitude = nil; + + if (placeGeometryDictionary) { + placeLocationDictionary = [placeGeometryDictionary objectForKey:@"location"]; + } + + if (placeLocationDictionary) { + latitude = [placeLocationDictionary objectForKey:@"lat"]; + longitude = [placeLocationDictionary objectForKey:@"lng"]; + } + + if (latitude && longitude) { + CLLocation *placeLocation = [[CLLocation alloc] initWithLatitude:[latitude doubleValue] longitude:[longitude doubleValue]]; + [[self geocoder] reverseGeocodeLocation:placeLocation completionHandler:^(NSArray *placemarks, NSError *error) { + if (error) { + block(nil, nil, error); + } else { + CLPlacemark *placemark = [placemarks firstObject]; + block(placemark, self.name, error); + } + }]; + } else if (placeAddress) { + [[self geocoder] geocodeAddressString:placeAddress completionHandler:^(NSArray *placemarks, NSError *error) { + if (error) { + block(nil, nil, error); + } else { + CLPlacemark *placemark = [placemarks firstObject]; + block(placemark, self.name, error); + } + }]; } else { - CLPlacemark *placemark = [placemarks onlyObject]; - block(placemark, self.name, error); + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey:NSLocalizedString(@"Could not resolve place.", nil) }; + error = [[NSError alloc] initWithDomain:@"com.spoletto.googleplaces" code:kGoogleAPINSErrorCode userInfo:userInfo]; + + block(nil, self.name, error); } - }]; + } else { + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey:NSLocalizedString(@"Could not resolve place.", nil) }; + error = [[NSError alloc] initWithDomain:@"com.spoletto.googleplaces" code:kGoogleAPINSErrorCode userInfo:userInfo]; + + block(nil, self.name, error); + } } }]; } @@ -66,27 +106,21 @@ - (void)resolveGecodePlaceToPlacemark:(SPGooglePlacesPlacemarkResultBlock)block if (error) { block(nil, nil, error); } else { - CLPlacemark *placemark = [placemarks onlyObject]; + CLPlacemark *placemark = [placemarks firstObject]; block(placemark, self.name, error); } }]; } - (void)resolveToPlacemark:(SPGooglePlacesPlacemarkResultBlock)block { - if (type == SPPlaceTypeGeocode) { + if (self.identifier.length > 0) { + // If there is already a Google Place API reference number, there should + // not be a need to attempt to geocode using the (inexact) address. + [self resolveReferenceIdentifierToPlacemark:block]; + } else { // Geocode places already have their address stored in the 'name' field. [self resolveGecodePlaceToPlacemark:block]; - } else { - [self resolveEstablishmentPlaceToPlacemark:block]; } } -- (void)dealloc { - [name release]; - [reference release]; - [identifier release]; - [geocoder release]; - [super dealloc]; -} - @end diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.m b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.m index 2faf0f1..2a526fe 100644 --- a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.m +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteQuery.m @@ -18,7 +18,7 @@ @implementation SPGooglePlacesAutocompleteQuery @synthesize input, sensor, key, offset, location, radius, language, types, resultBlock; + (SPGooglePlacesAutocompleteQuery *)query { - return [[[self alloc] init] autorelease]; + return [[self alloc] init]; } - (id)init { @@ -39,21 +39,12 @@ - (NSString *)description { return [NSString stringWithFormat:@"Query URL: %@", [self googleURLString]]; } -- (void)dealloc { - [googleConnection release]; - [responseData release]; - [input release]; - [key release]; - [language release]; - [super dealloc]; -} - - (NSString *)googleURLString { NSMutableString *url = [NSMutableString stringWithFormat:@"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%@&sensor=%@&key=%@", [input stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], SPBooleanStringForBool(sensor), key]; if (offset != NSNotFound) { - [url appendFormat:@"&offset=%u", offset]; + [url appendFormat:@"&offset=%lu", (unsigned long)offset]; } if (location.latitude != -1) { [url appendFormat:@"&location=%f,%f", location.latitude, location.longitude]; @@ -71,8 +62,6 @@ - (NSString *)googleURLString { } - (void)cleanup { - [googleConnection release]; - [responseData release]; googleConnection = nil; responseData = nil; self.resultBlock = nil; diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.h b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.h index e10ab95..5829233 100644 --- a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.h +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.h @@ -11,10 +11,11 @@ @class CLPlacemark; -typedef enum { +typedef NS_ENUM(NSInteger, SPGooglePlacesAutocompletePlaceType) { + SPPlaceTypeUnknown = -1, SPPlaceTypeGeocode = 0, - SPPlaceTypeEstablishment -} SPGooglePlacesAutocompletePlaceType; + SPPlaceTypeEstablishment = 1 +}; typedef void (^SPGooglePlacesPlacemarkResultBlock)(CLPlacemark *placemark, NSString *addressString, NSError *error); typedef void (^SPGooglePlacesAutocompleteResultBlock)(NSArray *places, NSError *error); diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.m b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.m index 894e743..7335ff2 100644 --- a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.m +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteUtilities.m @@ -32,7 +32,6 @@ BOOL SPEnsureGoogleAPIKey() { userHasProvidedAPIKey = NO; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"API Key Needed" message:@"Please replace kGoogleAPIKey with your Google API key." delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil]; [alert show]; - [alert release]; } return userHasProvidedAPIKey; } @@ -40,7 +39,6 @@ BOOL SPEnsureGoogleAPIKey() { void SPPresentAlertViewWithErrorAndTitle(NSError *error, NSString *title) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:[error localizedDescription] delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil]; [alert show]; - [alert release]; } extern BOOL SPIsEmptyString(NSString *string) { diff --git a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteViewController.m b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteViewController.m index d959b89..7f6da4f 100644 --- a/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteViewController.m +++ b/SPGooglePlacesAutocomplete/SPGooglePlacesAutocompleteViewController.m @@ -36,13 +36,6 @@ - (void)viewDidUnload { [super viewDidUnload]; } -- (void)dealloc { - [selectedPlaceAnnotation release]; - [mapView release]; - [searchQuery release]; - [super dealloc]; -} - - (IBAction)recenterMapToUserLocation:(id)sender { MKCoordinateRegion region; MKCoordinateSpan span; @@ -71,7 +64,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N static NSString *cellIdentifier = @"SPGooglePlacesAutocompleteCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (!cell) { - cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease]; + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } cell.textLabel.font = [UIFont fontWithName:@"GillSans" size:16.0]; @@ -97,7 +90,6 @@ - (void)recenterMapToPlacemark:(CLPlacemark *)placemark { - (void)addPlacemarkAnnotationToMap:(CLPlacemark *)placemark addressString:(NSString *)address { [self.mapView removeAnnotation:selectedPlaceAnnotation]; - [selectedPlaceAnnotation release]; selectedPlaceAnnotation = [[MKPointAnnotation alloc] init]; selectedPlaceAnnotation.coordinate = placemark.location.coordinate; @@ -137,12 +129,16 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath - (void)handleSearchForSearchString:(NSString *)searchString { searchQuery.location = self.mapView.userLocation.coordinate; searchQuery.input = searchString; + + __weak SPGooglePlacesAutocompleteViewController *weakSelf = self; + [searchQuery fetchPlaces:^(NSArray *places, NSError *error) { + __strong SPGooglePlacesAutocompleteViewController *strongSelf = weakSelf; + if (error) { SPPresentAlertViewWithErrorAndTitle(error, @"Could not fetch Places"); } else { - [searchResultPlaces release]; - searchResultPlaces = [places retain]; + strongSelf->searchResultPlaces = places; [self.searchDisplayController.searchResultsTableView reloadData]; } }]; @@ -193,7 +189,7 @@ - (MKAnnotationView *)mapView:(MKMapView *)mapViewIn viewForAnnotation:(id