├── .gitignore ├── Demo ├── Classes │ ├── SVGeocoderAppAppDelegate.h │ ├── SVGeocoderAppAppDelegate.m │ ├── SVGeocoderAppViewController.h │ └── SVGeocoderAppViewController.m ├── Default-568h@2x.png ├── MainWindow.xib ├── SVGeocoder.xcodeproj │ └── project.pbxproj ├── SVGeocoderApp-Info.plist ├── SVGeocoderAppViewController.xib ├── SVGeocoder_Prefix.pch └── main.m ├── LICENSE.txt ├── README.textile ├── SVGeocoder.podspec └── SVGeocoder ├── SVGeocoder.h ├── SVGeocoder.m ├── SVPlacemark.h └── SVPlacemark.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac OS X 2 | *.DS_Store 3 | *.psd 4 | 5 | # Xcode 6 | *.pbxuser 7 | *.mode1v3 8 | *.mode2v3 9 | *.perspectivev3 10 | *.xcuserstate 11 | project.xcworkspace/ 12 | xcuserdata/ 13 | 14 | # Generated files 15 | build/ 16 | *.[oa] 17 | *.pyc 18 | 19 | # Backup files 20 | *~.nib -------------------------------------------------------------------------------- /Demo/Classes/SVGeocoderAppAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMGeocoderAppAppDelegate.h 3 | // SMGeocoderApp 4 | // 5 | // Created by Sam Vermette on 11.02.11. 6 | // Copyright 2011 Sam Vermette. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SVGeocoderAppViewController; 12 | 13 | @interface SVGeocoderAppAppDelegate : NSObject { 14 | UIWindow *window; 15 | SVGeocoderAppViewController *viewController; 16 | } 17 | 18 | @property (nonatomic, strong) IBOutlet UIWindow *window; 19 | @property (nonatomic, strong) IBOutlet SVGeocoderAppViewController *viewController; 20 | 21 | @end 22 | 23 | -------------------------------------------------------------------------------- /Demo/Classes/SVGeocoderAppAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMGeocoderAppAppDelegate.m 3 | // SMGeocoderApp 4 | // 5 | // Created by Sam Vermette on 11.02.11. 6 | // Copyright 2011 Sam Vermette. All rights reserved. 7 | // 8 | 9 | #import "SVGeocoderAppAppDelegate.h" 10 | #import "SVGeocoderAppViewController.h" 11 | 12 | @implementation SVGeocoderAppAppDelegate 13 | 14 | @synthesize window; 15 | @synthesize viewController; 16 | 17 | 18 | #pragma mark - 19 | #pragma mark Application lifecycle 20 | 21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 22 | 23 | // Override point for customization after application launch. 24 | 25 | // Add the view controller's view to the window and display. 26 | [self.window addSubview:viewController.view]; 27 | [self.window makeKeyAndVisible]; 28 | 29 | [SVGeocoder setGoogleMapsAPIKey:@"KEY"]; 30 | 31 | return YES; 32 | } 33 | 34 | 35 | - (void)applicationWillResignActive:(UIApplication *)application { 36 | /* 37 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 38 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 39 | */ 40 | } 41 | 42 | 43 | - (void)applicationDidEnterBackground:(UIApplication *)application { 44 | /* 45 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 46 | If your application supports background execution, called instead of applicationWillTerminate: when the user quits. 47 | */ 48 | } 49 | 50 | 51 | - (void)applicationWillEnterForeground:(UIApplication *)application { 52 | /* 53 | Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background. 54 | */ 55 | } 56 | 57 | 58 | - (void)applicationDidBecomeActive:(UIApplication *)application { 59 | /* 60 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 61 | */ 62 | } 63 | 64 | 65 | - (void)applicationWillTerminate:(UIApplication *)application { 66 | /* 67 | Called when the application is about to terminate. 68 | See also applicationDidEnterBackground:. 69 | */ 70 | } 71 | 72 | 73 | #pragma mark - 74 | #pragma mark Memory management 75 | 76 | - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { 77 | /* 78 | Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later. 79 | */ 80 | } 81 | 82 | 83 | 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /Demo/Classes/SVGeocoderAppViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVGeocoderAppViewController.h 3 | // SVGeocoderApp 4 | // 5 | // Created by Sam Vermette on 11.02.11. 6 | // Copyright 2011 Sam Vermette. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SVGeocoder.h" 11 | 12 | @interface SVGeocoderAppViewController : UIViewController { 13 | IBOutlet UITextField *latField, *lngField, *addressField; 14 | } 15 | 16 | - (IBAction)reverseGeocode; 17 | - (IBAction)geocode; 18 | 19 | @end 20 | 21 | -------------------------------------------------------------------------------- /Demo/Classes/SVGeocoderAppViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVGeocoderAppViewController.m 3 | // SVGeocoderApp 4 | // 5 | // Created by Sam Vermette on 11.02.11. 6 | // Copyright 2011 Sam Vermette. All rights reserved. 7 | // 8 | 9 | #import "SVGeocoderAppViewController.h" 10 | 11 | 12 | @implementation SVGeocoderAppViewController 13 | 14 | 15 | - (void)reverseGeocode { 16 | [SVGeocoder reverseGeocode:CLLocationCoordinate2DMake(latField.text.floatValue, lngField.text.floatValue) 17 | completion:^(NSArray *placemarks, NSHTTPURLResponse *urlResponse, NSError *error) { 18 | NSLog(@"placemarks = %@", placemarks); 19 | }]; 20 | } 21 | 22 | - (void)geocode { 23 | [SVGeocoder geocode:addressField.text 24 | completion:^(NSArray *placemarks, NSHTTPURLResponse *urlResponse, NSError *error) { 25 | NSLog(@"placemarks = %@", placemarks); 26 | }]; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Demo/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TransitApp/SVGeocoder/a8b06cddace211db94dbc41bf3eaa473cefe08a8/Demo/Default-568h@2x.png -------------------------------------------------------------------------------- /Demo/MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1056 5 | 10J567 6 | 823 7 | 1038.35 8 | 462.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 132 12 | 13 | 14 | YES 15 | 16 | 17 | YES 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | YES 22 | 23 | YES 24 | 25 | 26 | YES 27 | 28 | 29 | 30 | YES 31 | 32 | IBFilesOwner 33 | IBCocoaTouchFramework 34 | 35 | 36 | IBFirstResponder 37 | IBCocoaTouchFramework 38 | 39 | 40 | IBCocoaTouchFramework 41 | 42 | 43 | SVGeocoderAppViewController 44 | 45 | 46 | 1 47 | 48 | IBCocoaTouchFramework 49 | NO 50 | 51 | 52 | 53 | 292 54 | {320, 480} 55 | 56 | 1 57 | MSAxIDEAA 58 | 59 | NO 60 | NO 61 | 62 | IBCocoaTouchFramework 63 | YES 64 | 65 | 66 | 67 | 68 | YES 69 | 70 | 71 | delegate 72 | 73 | 74 | 75 | 4 76 | 77 | 78 | 79 | viewController 80 | 81 | 82 | 83 | 11 84 | 85 | 86 | 87 | window 88 | 89 | 90 | 91 | 14 92 | 93 | 94 | 95 | 96 | YES 97 | 98 | 0 99 | 100 | 101 | 102 | 103 | 104 | -1 105 | 106 | 107 | File's Owner 108 | 109 | 110 | 3 111 | 112 | 113 | SMGeocoderApp App Delegate 114 | 115 | 116 | -2 117 | 118 | 119 | 120 | 121 | 10 122 | 123 | 124 | 125 | 126 | 12 127 | 128 | 129 | 130 | 131 | 132 | 133 | YES 134 | 135 | YES 136 | -1.CustomClassName 137 | -2.CustomClassName 138 | 10.CustomClassName 139 | 10.IBEditorWindowLastContentRect 140 | 10.IBPluginDependency 141 | 12.IBEditorWindowLastContentRect 142 | 12.IBPluginDependency 143 | 3.CustomClassName 144 | 3.IBPluginDependency 145 | 146 | 147 | YES 148 | UIApplication 149 | UIResponder 150 | SVGeocoderAppViewController 151 | {{234, 376}, {320, 480}} 152 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 153 | {{525, 346}, {320, 480}} 154 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 155 | SVGeocoderAppAppDelegate 156 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 157 | 158 | 159 | 160 | YES 161 | 162 | 163 | YES 164 | 165 | 166 | 167 | 168 | YES 169 | 170 | 171 | YES 172 | 173 | 174 | 175 | 15 176 | 177 | 178 | 179 | YES 180 | 181 | SVGeocoderAppAppDelegate 182 | NSObject 183 | 184 | YES 185 | 186 | YES 187 | viewController 188 | window 189 | 190 | 191 | YES 192 | SVGeocoderAppViewController 193 | UIWindow 194 | 195 | 196 | 197 | YES 198 | 199 | YES 200 | viewController 201 | window 202 | 203 | 204 | YES 205 | 206 | viewController 207 | SVGeocoderAppViewController 208 | 209 | 210 | window 211 | UIWindow 212 | 213 | 214 | 215 | 216 | IBProjectSource 217 | Classes/SVGeocoderAppAppDelegate.h 218 | 219 | 220 | 221 | SVGeocoderAppAppDelegate 222 | NSObject 223 | 224 | IBUserSource 225 | 226 | 227 | 228 | 229 | SVGeocoderAppViewController 230 | UIViewController 231 | 232 | YES 233 | 234 | YES 235 | geocode 236 | reverseGeocode 237 | 238 | 239 | YES 240 | id 241 | id 242 | 243 | 244 | 245 | YES 246 | 247 | YES 248 | geocode 249 | reverseGeocode 250 | 251 | 252 | YES 253 | 254 | geocode 255 | id 256 | 257 | 258 | reverseGeocode 259 | id 260 | 261 | 262 | 263 | 264 | YES 265 | 266 | YES 267 | addressField 268 | latField 269 | lngField 270 | 271 | 272 | YES 273 | UITextField 274 | UITextField 275 | UITextField 276 | 277 | 278 | 279 | YES 280 | 281 | YES 282 | addressField 283 | latField 284 | lngField 285 | 286 | 287 | YES 288 | 289 | addressField 290 | UITextField 291 | 292 | 293 | latField 294 | UITextField 295 | 296 | 297 | lngField 298 | UITextField 299 | 300 | 301 | 302 | 303 | IBProjectSource 304 | Classes/SVGeocoderAppViewController.h 305 | 306 | 307 | 308 | UIWindow 309 | UIView 310 | 311 | IBUserSource 312 | 313 | 314 | 315 | 316 | 317 | YES 318 | 319 | NSObject 320 | 321 | IBFrameworkSource 322 | Foundation.framework/Headers/NSError.h 323 | 324 | 325 | 326 | NSObject 327 | 328 | IBFrameworkSource 329 | Foundation.framework/Headers/NSFileManager.h 330 | 331 | 332 | 333 | NSObject 334 | 335 | IBFrameworkSource 336 | Foundation.framework/Headers/NSKeyValueCoding.h 337 | 338 | 339 | 340 | NSObject 341 | 342 | IBFrameworkSource 343 | Foundation.framework/Headers/NSKeyValueObserving.h 344 | 345 | 346 | 347 | NSObject 348 | 349 | IBFrameworkSource 350 | Foundation.framework/Headers/NSKeyedArchiver.h 351 | 352 | 353 | 354 | NSObject 355 | 356 | IBFrameworkSource 357 | Foundation.framework/Headers/NSObject.h 358 | 359 | 360 | 361 | NSObject 362 | 363 | IBFrameworkSource 364 | Foundation.framework/Headers/NSRunLoop.h 365 | 366 | 367 | 368 | NSObject 369 | 370 | IBFrameworkSource 371 | Foundation.framework/Headers/NSThread.h 372 | 373 | 374 | 375 | NSObject 376 | 377 | IBFrameworkSource 378 | Foundation.framework/Headers/NSURL.h 379 | 380 | 381 | 382 | NSObject 383 | 384 | IBFrameworkSource 385 | Foundation.framework/Headers/NSURLConnection.h 386 | 387 | 388 | 389 | NSObject 390 | 391 | IBFrameworkSource 392 | UIKit.framework/Headers/UIAccessibility.h 393 | 394 | 395 | 396 | NSObject 397 | 398 | IBFrameworkSource 399 | UIKit.framework/Headers/UINibLoading.h 400 | 401 | 402 | 403 | NSObject 404 | 405 | IBFrameworkSource 406 | UIKit.framework/Headers/UIResponder.h 407 | 408 | 409 | 410 | UIApplication 411 | UIResponder 412 | 413 | IBFrameworkSource 414 | UIKit.framework/Headers/UIApplication.h 415 | 416 | 417 | 418 | UIControl 419 | UIView 420 | 421 | IBFrameworkSource 422 | UIKit.framework/Headers/UIControl.h 423 | 424 | 425 | 426 | UIResponder 427 | NSObject 428 | 429 | 430 | 431 | UISearchBar 432 | UIView 433 | 434 | IBFrameworkSource 435 | UIKit.framework/Headers/UISearchBar.h 436 | 437 | 438 | 439 | UISearchDisplayController 440 | NSObject 441 | 442 | IBFrameworkSource 443 | UIKit.framework/Headers/UISearchDisplayController.h 444 | 445 | 446 | 447 | UITextField 448 | UIControl 449 | 450 | IBFrameworkSource 451 | UIKit.framework/Headers/UITextField.h 452 | 453 | 454 | 455 | UIView 456 | 457 | IBFrameworkSource 458 | UIKit.framework/Headers/UIPrintFormatter.h 459 | 460 | 461 | 462 | UIView 463 | 464 | 465 | 466 | UIView 467 | UIResponder 468 | 469 | IBFrameworkSource 470 | UIKit.framework/Headers/UIView.h 471 | 472 | 473 | 474 | UIViewController 475 | 476 | IBFrameworkSource 477 | UIKit.framework/Headers/UINavigationController.h 478 | 479 | 480 | 481 | UIViewController 482 | 483 | IBFrameworkSource 484 | UIKit.framework/Headers/UIPopoverController.h 485 | 486 | 487 | 488 | UIViewController 489 | 490 | IBFrameworkSource 491 | UIKit.framework/Headers/UISplitViewController.h 492 | 493 | 494 | 495 | UIViewController 496 | 497 | IBFrameworkSource 498 | UIKit.framework/Headers/UITabBarController.h 499 | 500 | 501 | 502 | UIViewController 503 | UIResponder 504 | 505 | IBFrameworkSource 506 | UIKit.framework/Headers/UIViewController.h 507 | 508 | 509 | 510 | UIWindow 511 | UIView 512 | 513 | IBFrameworkSource 514 | UIKit.framework/Headers/UIWindow.h 515 | 516 | 517 | 518 | 519 | 0 520 | IBCocoaTouchFramework 521 | 522 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 523 | 524 | 525 | 526 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 527 | 528 | 529 | YES 530 | SMGeocoderApp.xcodeproj 531 | 3 532 | 132 533 | 534 | 535 | -------------------------------------------------------------------------------- /Demo/SVGeocoder.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1D3623260D0F684500981E51 /* SVGeocoderAppAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* SVGeocoderAppAppDelegate.m */; }; 11 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 12 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 13 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 14 | 2215D386136DE916007A3351 /* SVPlacemark.m in Sources */ = {isa = PBXBuildFile; fileRef = 2215D385136DE916007A3351 /* SVPlacemark.m */; }; 15 | 2273178C14B7511A00A25F46 /* README.textile in Resources */ = {isa = PBXBuildFile; fileRef = 2273178B14B7511A00A25F46 /* README.textile */; }; 16 | 227829E313061C8C00CCA1B9 /* SVGeocoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 227829CB13061C8C00CCA1B9 /* SVGeocoder.m */; }; 17 | 22B7DFEB1305BA250014DB40 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22B7DFEA1305BA250014DB40 /* MapKit.framework */; }; 18 | 22B7DFFD1305BA380014DB40 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22B7DFFC1305BA380014DB40 /* CoreLocation.framework */; }; 19 | 22E18A6F1615490F00F13D32 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 22E18A6E1615490F00F13D32 /* Default-568h@2x.png */; }; 20 | 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; 21 | 2899E5220DE3E06400AC0155 /* SVGeocoderAppViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2899E5210DE3E06400AC0155 /* SVGeocoderAppViewController.xib */; }; 22 | 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 23 | 28D7ACF80DDB3853001CB0EB /* SVGeocoderAppViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* SVGeocoderAppViewController.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 28 | 1D3623240D0F684500981E51 /* SVGeocoderAppAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGeocoderAppAppDelegate.h; sourceTree = ""; }; 29 | 1D3623250D0F684500981E51 /* SVGeocoderAppAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGeocoderAppAppDelegate.m; sourceTree = ""; }; 30 | 1D6058910D05DD3D006BFB54 /* SVGeocoder.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SVGeocoder.app; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 32 | 2215D384136DE916007A3351 /* SVPlacemark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVPlacemark.h; sourceTree = ""; }; 33 | 2215D385136DE916007A3351 /* SVPlacemark.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVPlacemark.m; sourceTree = ""; }; 34 | 2273178B14B7511A00A25F46 /* README.textile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.textile; path = ../README.textile; sourceTree = ""; }; 35 | 227829CA13061C8C00CCA1B9 /* SVGeocoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGeocoder.h; sourceTree = ""; }; 36 | 227829CB13061C8C00CCA1B9 /* SVGeocoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGeocoder.m; sourceTree = ""; }; 37 | 22B7DFEA1305BA250014DB40 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; 38 | 22B7DFFC1305BA380014DB40 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; 39 | 22E18A6E1615490F00F13D32 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 40 | 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 41 | 2899E5210DE3E06400AC0155 /* SVGeocoderAppViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SVGeocoderAppViewController.xib; sourceTree = ""; }; 42 | 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; 43 | 28D7ACF60DDB3853001CB0EB /* SVGeocoderAppViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGeocoderAppViewController.h; sourceTree = ""; }; 44 | 28D7ACF70DDB3853001CB0EB /* SVGeocoderAppViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGeocoderAppViewController.m; sourceTree = ""; }; 45 | 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | 32CA4F630368D1EE00C91783 /* SVGeocoder_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGeocoder_Prefix.pch; sourceTree = ""; }; 47 | 8D1107310486CEB800E47090 /* SVGeocoderApp-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SVGeocoderApp-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; 48 | /* End PBXFileReference section */ 49 | 50 | /* Begin PBXFrameworksBuildPhase section */ 51 | 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, 56 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, 57 | 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, 58 | 22B7DFEB1305BA250014DB40 /* MapKit.framework in Frameworks */, 59 | 22B7DFFD1305BA380014DB40 /* CoreLocation.framework in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | 080E96DDFE201D6D7F000001 /* Classes */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 1D3623240D0F684500981E51 /* SVGeocoderAppAppDelegate.h */, 70 | 1D3623250D0F684500981E51 /* SVGeocoderAppAppDelegate.m */, 71 | 28D7ACF60DDB3853001CB0EB /* SVGeocoderAppViewController.h */, 72 | 28D7ACF70DDB3853001CB0EB /* SVGeocoderAppViewController.m */, 73 | ); 74 | path = Classes; 75 | sourceTree = ""; 76 | }; 77 | 19C28FACFE9D520D11CA2CBB /* Products */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 1D6058910D05DD3D006BFB54 /* SVGeocoder.app */, 81 | ); 82 | name = Products; 83 | sourceTree = ""; 84 | }; 85 | 227829C913061C8C00CCA1B9 /* SVGeocoder */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 227829CA13061C8C00CCA1B9 /* SVGeocoder.h */, 89 | 227829CB13061C8C00CCA1B9 /* SVGeocoder.m */, 90 | 2215D384136DE916007A3351 /* SVPlacemark.h */, 91 | 2215D385136DE916007A3351 /* SVPlacemark.m */, 92 | ); 93 | name = SVGeocoder; 94 | path = ../SVGeocoder; 95 | sourceTree = SOURCE_ROOT; 96 | }; 97 | 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 22E18A6E1615490F00F13D32 /* Default-568h@2x.png */, 101 | 2273178B14B7511A00A25F46 /* README.textile */, 102 | 080E96DDFE201D6D7F000001 /* Classes */, 103 | 227829C913061C8C00CCA1B9 /* SVGeocoder */, 104 | 29B97315FDCFA39411CA2CEA /* Other Sources */, 105 | 29B97317FDCFA39411CA2CEA /* Resources */, 106 | 29B97323FDCFA39411CA2CEA /* Frameworks */, 107 | 19C28FACFE9D520D11CA2CBB /* Products */, 108 | ); 109 | name = CustomTemplate; 110 | sourceTree = ""; 111 | }; 112 | 29B97315FDCFA39411CA2CEA /* Other Sources */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 32CA4F630368D1EE00C91783 /* SVGeocoder_Prefix.pch */, 116 | 29B97316FDCFA39411CA2CEA /* main.m */, 117 | ); 118 | name = "Other Sources"; 119 | sourceTree = ""; 120 | }; 121 | 29B97317FDCFA39411CA2CEA /* Resources */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 2899E5210DE3E06400AC0155 /* SVGeocoderAppViewController.xib */, 125 | 28AD733E0D9D9553002E5188 /* MainWindow.xib */, 126 | 8D1107310486CEB800E47090 /* SVGeocoderApp-Info.plist */, 127 | ); 128 | name = Resources; 129 | sourceTree = ""; 130 | }; 131 | 29B97323FDCFA39411CA2CEA /* Frameworks */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 22B7DFFC1305BA380014DB40 /* CoreLocation.framework */, 135 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, 136 | 1D30AB110D05D00D00671497 /* Foundation.framework */, 137 | 288765A40DF7441C002DB57D /* CoreGraphics.framework */, 138 | 22B7DFEA1305BA250014DB40 /* MapKit.framework */, 139 | ); 140 | name = Frameworks; 141 | sourceTree = ""; 142 | }; 143 | /* End PBXGroup section */ 144 | 145 | /* Begin PBXNativeTarget section */ 146 | 1D6058900D05DD3D006BFB54 /* SVGeocoder */ = { 147 | isa = PBXNativeTarget; 148 | buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SVGeocoder" */; 149 | buildPhases = ( 150 | 1D60588D0D05DD3D006BFB54 /* Resources */, 151 | 1D60588E0D05DD3D006BFB54 /* Sources */, 152 | 1D60588F0D05DD3D006BFB54 /* Frameworks */, 153 | ); 154 | buildRules = ( 155 | ); 156 | dependencies = ( 157 | ); 158 | name = SVGeocoder; 159 | productName = SMGeocoderApp; 160 | productReference = 1D6058910D05DD3D006BFB54 /* SVGeocoder.app */; 161 | productType = "com.apple.product-type.application"; 162 | }; 163 | /* End PBXNativeTarget section */ 164 | 165 | /* Begin PBXProject section */ 166 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 167 | isa = PBXProject; 168 | attributes = { 169 | LastUpgradeCheck = 0450; 170 | }; 171 | buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SVGeocoder" */; 172 | compatibilityVersion = "Xcode 3.2"; 173 | developmentRegion = English; 174 | hasScannedForEncodings = 1; 175 | knownRegions = ( 176 | English, 177 | Japanese, 178 | French, 179 | German, 180 | ); 181 | mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; 182 | projectDirPath = ""; 183 | projectRoot = ""; 184 | targets = ( 185 | 1D6058900D05DD3D006BFB54 /* SVGeocoder */, 186 | ); 187 | }; 188 | /* End PBXProject section */ 189 | 190 | /* Begin PBXResourcesBuildPhase section */ 191 | 1D60588D0D05DD3D006BFB54 /* Resources */ = { 192 | isa = PBXResourcesBuildPhase; 193 | buildActionMask = 2147483647; 194 | files = ( 195 | 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, 196 | 2899E5220DE3E06400AC0155 /* SVGeocoderAppViewController.xib in Resources */, 197 | 2273178C14B7511A00A25F46 /* README.textile in Resources */, 198 | 22E18A6F1615490F00F13D32 /* Default-568h@2x.png in Resources */, 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | }; 202 | /* End PBXResourcesBuildPhase section */ 203 | 204 | /* Begin PBXSourcesBuildPhase section */ 205 | 1D60588E0D05DD3D006BFB54 /* Sources */ = { 206 | isa = PBXSourcesBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */, 210 | 1D3623260D0F684500981E51 /* SVGeocoderAppAppDelegate.m in Sources */, 211 | 28D7ACF80DDB3853001CB0EB /* SVGeocoderAppViewController.m in Sources */, 212 | 227829E313061C8C00CCA1B9 /* SVGeocoder.m in Sources */, 213 | 2215D386136DE916007A3351 /* SVPlacemark.m in Sources */, 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | }; 217 | /* End PBXSourcesBuildPhase section */ 218 | 219 | /* Begin XCBuildConfiguration section */ 220 | 1D6058940D05DD3E006BFB54 /* Debug */ = { 221 | isa = XCBuildConfiguration; 222 | buildSettings = { 223 | ALWAYS_SEARCH_USER_PATHS = NO; 224 | CLANG_ENABLE_OBJC_ARC = YES; 225 | COPY_PHASE_STRIP = NO; 226 | GCC_DYNAMIC_NO_PIC = NO; 227 | GCC_OPTIMIZATION_LEVEL = 0; 228 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 229 | GCC_PREFIX_HEADER = SVGeocoder_Prefix.pch; 230 | INFOPLIST_FILE = "SVGeocoderApp-Info.plist"; 231 | PRODUCT_NAME = SVGeocoder; 232 | }; 233 | name = Debug; 234 | }; 235 | 1D6058950D05DD3E006BFB54 /* Release */ = { 236 | isa = XCBuildConfiguration; 237 | buildSettings = { 238 | ALWAYS_SEARCH_USER_PATHS = NO; 239 | CLANG_ENABLE_OBJC_ARC = YES; 240 | COPY_PHASE_STRIP = YES; 241 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 242 | GCC_PREFIX_HEADER = SVGeocoder_Prefix.pch; 243 | INFOPLIST_FILE = "SVGeocoderApp-Info.plist"; 244 | PRODUCT_NAME = SVGeocoder; 245 | VALIDATE_PRODUCT = YES; 246 | }; 247 | name = Release; 248 | }; 249 | C01FCF4F08A954540054247B /* Debug */ = { 250 | isa = XCBuildConfiguration; 251 | buildSettings = { 252 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 253 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 254 | GCC_C_LANGUAGE_STANDARD = c99; 255 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 256 | GCC_WARN_UNUSED_VARIABLE = YES; 257 | SDKROOT = iphoneos; 258 | }; 259 | name = Debug; 260 | }; 261 | C01FCF5008A954540054247B /* Release */ = { 262 | isa = XCBuildConfiguration; 263 | buildSettings = { 264 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 265 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 266 | GCC_C_LANGUAGE_STANDARD = c99; 267 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 268 | GCC_WARN_UNUSED_VARIABLE = YES; 269 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 270 | SDKROOT = iphoneos; 271 | }; 272 | name = Release; 273 | }; 274 | /* End XCBuildConfiguration section */ 275 | 276 | /* Begin XCConfigurationList section */ 277 | 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SVGeocoder" */ = { 278 | isa = XCConfigurationList; 279 | buildConfigurations = ( 280 | 1D6058940D05DD3E006BFB54 /* Debug */, 281 | 1D6058950D05DD3E006BFB54 /* Release */, 282 | ); 283 | defaultConfigurationIsVisible = 0; 284 | defaultConfigurationName = Release; 285 | }; 286 | C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SVGeocoder" */ = { 287 | isa = XCConfigurationList; 288 | buildConfigurations = ( 289 | C01FCF4F08A954540054247B /* Debug */, 290 | C01FCF5008A954540054247B /* Release */, 291 | ); 292 | defaultConfigurationIsVisible = 0; 293 | defaultConfigurationName = Release; 294 | }; 295 | /* End XCConfigurationList section */ 296 | }; 297 | rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; 298 | } 299 | -------------------------------------------------------------------------------- /Demo/SVGeocoderApp-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | com.yourcompany.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | NSMainNibFile 28 | MainWindow 29 | 30 | 31 | -------------------------------------------------------------------------------- /Demo/SVGeocoderAppViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1056 5 | 10J567 6 | 823 7 | 1038.35 8 | 462.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 132 12 | 13 | 14 | YES 15 | 16 | 17 | 18 | YES 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | YES 23 | 24 | YES 25 | 26 | 27 | YES 28 | 29 | 30 | 31 | YES 32 | 33 | IBFilesOwner 34 | IBCocoaTouchFramework 35 | 36 | 37 | IBFirstResponder 38 | IBCocoaTouchFramework 39 | 40 | 41 | 42 | 274 43 | 44 | YES 45 | 46 | 47 | 292 48 | {{48, 63}, {225, 44}} 49 | 50 | NO 51 | IBCocoaTouchFramework 52 | 0 53 | 0 54 | 55 | Helvetica-Bold 56 | 17 57 | 16 58 | 59 | 1 60 | Reverse Geocode 61 | 62 | 3 63 | MQA 64 | 65 | 66 | 1 67 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 68 | 69 | 70 | 3 71 | MC41AA 72 | 73 | 74 | 75 | 76 | 292 77 | {{48, 183}, {225, 44}} 78 | 79 | NO 80 | IBCocoaTouchFramework 81 | 0 82 | 0 83 | 84 | 1 85 | Geocode 86 | 87 | 88 | 1 89 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 90 | 91 | 92 | 93 | 94 | 95 | 292 96 | {{48, 141}, {225, 31}} 97 | 98 | NO 99 | YES 100 | IBCocoaTouchFramework 101 | 0 102 | 103 | 3 104 | Address or city 105 | 106 | 3 107 | MAA 108 | 109 | 2 110 | 111 | 112 | 113 | Helvetica 114 | 14 115 | 16 116 | 117 | YES 118 | 17 119 | 120 | IBCocoaTouchFramework 121 | 122 | 123 | 124 | 125 | 292 126 | {{48, 21}, {104, 31}} 127 | 128 | NO 129 | YES 130 | IBCocoaTouchFramework 131 | 0 132 | 133 | 3 134 | Latitude 135 | 136 | 3 137 | MAA 138 | 139 | 140 | 141 | YES 142 | 17 143 | 144 | IBCocoaTouchFramework 145 | 146 | 147 | 148 | 149 | 292 150 | {{169, 20}, {104, 31}} 151 | 152 | NO 153 | YES 154 | IBCocoaTouchFramework 155 | 0 156 | 157 | 3 158 | Longitude 159 | 160 | 3 161 | MAA 162 | 163 | 164 | 165 | YES 166 | 17 167 | 168 | IBCocoaTouchFramework 169 | 170 | 171 | 172 | {320, 460} 173 | 174 | 175 | 3 176 | MC44NQA 177 | 178 | NO 179 | 180 | IBCocoaTouchFramework 181 | 182 | 183 | 184 | 185 | YES 186 | 187 | 188 | view 189 | 190 | 191 | 192 | 7 193 | 194 | 195 | 196 | latField 197 | 198 | 199 | 200 | 17 201 | 202 | 203 | 204 | lngField 205 | 206 | 207 | 208 | 18 209 | 210 | 211 | 212 | addressField 213 | 214 | 215 | 216 | 19 217 | 218 | 219 | 220 | geocode 221 | 222 | 223 | 7 224 | 225 | 20 226 | 227 | 228 | 229 | reverseGeocode 230 | 231 | 232 | 7 233 | 234 | 21 235 | 236 | 237 | 238 | 239 | YES 240 | 241 | 0 242 | 243 | 244 | 245 | 246 | 247 | -1 248 | 249 | 250 | File's Owner 251 | 252 | 253 | -2 254 | 255 | 256 | 257 | 258 | 6 259 | 260 | 261 | YES 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 8 272 | 273 | 274 | 275 | 276 | 9 277 | 278 | 279 | 280 | 281 | 11 282 | 283 | 284 | 285 | 286 | 15 287 | 288 | 289 | 290 | 291 | 16 292 | 293 | 294 | 295 | 296 | 297 | 298 | YES 299 | 300 | YES 301 | -1.CustomClassName 302 | -2.CustomClassName 303 | 11.IBPluginDependency 304 | 11.IBViewBoundsToFrameTransform 305 | 15.IBPluginDependency 306 | 15.IBViewBoundsToFrameTransform 307 | 16.IBPluginDependency 308 | 16.IBViewBoundsToFrameTransform 309 | 6.IBEditorWindowLastContentRect 310 | 6.IBPluginDependency 311 | 8.IBPluginDependency 312 | 8.IBViewBoundsToFrameTransform 313 | 9.IBPluginDependency 314 | 9.IBViewBoundsToFrameTransform 315 | 316 | 317 | YES 318 | SVGeocoderAppViewController 319 | UIResponder 320 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 321 | 322 | P4AAAL+AAABCdAAAw0oAAA 323 | 324 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 325 | 326 | P4AAAL+AAABCdAAAwoAAAA 327 | 328 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 329 | 330 | P4AAAL+AAABDNgAAwnwAAA 331 | 332 | {{563, 494}, {320, 480}} 333 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 334 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 335 | 336 | P4AAAL+AAABCdAAAwvYAAA 337 | 338 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 339 | 340 | P4AAAL+AAABCdAAAw4GAAA 341 | 342 | 343 | 344 | 345 | YES 346 | 347 | 348 | YES 349 | 350 | 351 | 352 | 353 | YES 354 | 355 | 356 | YES 357 | 358 | 359 | 360 | 21 361 | 362 | 363 | 364 | YES 365 | 366 | SVGeocoderAppViewController 367 | UIViewController 368 | 369 | YES 370 | 371 | YES 372 | geocode 373 | reverseGeocode 374 | 375 | 376 | YES 377 | id 378 | id 379 | 380 | 381 | 382 | YES 383 | 384 | YES 385 | geocode 386 | reverseGeocode 387 | 388 | 389 | YES 390 | 391 | geocode 392 | id 393 | 394 | 395 | reverseGeocode 396 | id 397 | 398 | 399 | 400 | 401 | YES 402 | 403 | YES 404 | addressField 405 | latField 406 | lngField 407 | 408 | 409 | YES 410 | UITextField 411 | UITextField 412 | UITextField 413 | 414 | 415 | 416 | YES 417 | 418 | YES 419 | addressField 420 | latField 421 | lngField 422 | 423 | 424 | YES 425 | 426 | addressField 427 | UITextField 428 | 429 | 430 | latField 431 | UITextField 432 | 433 | 434 | lngField 435 | UITextField 436 | 437 | 438 | 439 | 440 | IBProjectSource 441 | Classes/SVGeocoderAppViewController.h 442 | 443 | 444 | 445 | 446 | YES 447 | 448 | NSObject 449 | 450 | IBFrameworkSource 451 | Foundation.framework/Headers/NSError.h 452 | 453 | 454 | 455 | NSObject 456 | 457 | IBFrameworkSource 458 | Foundation.framework/Headers/NSFileManager.h 459 | 460 | 461 | 462 | NSObject 463 | 464 | IBFrameworkSource 465 | Foundation.framework/Headers/NSKeyValueCoding.h 466 | 467 | 468 | 469 | NSObject 470 | 471 | IBFrameworkSource 472 | Foundation.framework/Headers/NSKeyValueObserving.h 473 | 474 | 475 | 476 | NSObject 477 | 478 | IBFrameworkSource 479 | Foundation.framework/Headers/NSKeyedArchiver.h 480 | 481 | 482 | 483 | NSObject 484 | 485 | IBFrameworkSource 486 | Foundation.framework/Headers/NSObject.h 487 | 488 | 489 | 490 | NSObject 491 | 492 | IBFrameworkSource 493 | Foundation.framework/Headers/NSRunLoop.h 494 | 495 | 496 | 497 | NSObject 498 | 499 | IBFrameworkSource 500 | Foundation.framework/Headers/NSThread.h 501 | 502 | 503 | 504 | NSObject 505 | 506 | IBFrameworkSource 507 | Foundation.framework/Headers/NSURL.h 508 | 509 | 510 | 511 | NSObject 512 | 513 | IBFrameworkSource 514 | Foundation.framework/Headers/NSURLConnection.h 515 | 516 | 517 | 518 | NSObject 519 | 520 | IBFrameworkSource 521 | UIKit.framework/Headers/UIAccessibility.h 522 | 523 | 524 | 525 | NSObject 526 | 527 | IBFrameworkSource 528 | UIKit.framework/Headers/UINibLoading.h 529 | 530 | 531 | 532 | NSObject 533 | 534 | IBFrameworkSource 535 | UIKit.framework/Headers/UIResponder.h 536 | 537 | 538 | 539 | UIButton 540 | UIControl 541 | 542 | IBFrameworkSource 543 | UIKit.framework/Headers/UIButton.h 544 | 545 | 546 | 547 | UIControl 548 | UIView 549 | 550 | IBFrameworkSource 551 | UIKit.framework/Headers/UIControl.h 552 | 553 | 554 | 555 | UIResponder 556 | NSObject 557 | 558 | 559 | 560 | UISearchBar 561 | UIView 562 | 563 | IBFrameworkSource 564 | UIKit.framework/Headers/UISearchBar.h 565 | 566 | 567 | 568 | UISearchDisplayController 569 | NSObject 570 | 571 | IBFrameworkSource 572 | UIKit.framework/Headers/UISearchDisplayController.h 573 | 574 | 575 | 576 | UITextField 577 | UIControl 578 | 579 | IBFrameworkSource 580 | UIKit.framework/Headers/UITextField.h 581 | 582 | 583 | 584 | UIView 585 | 586 | IBFrameworkSource 587 | UIKit.framework/Headers/UIPrintFormatter.h 588 | 589 | 590 | 591 | UIView 592 | 593 | 594 | 595 | UIView 596 | UIResponder 597 | 598 | IBFrameworkSource 599 | UIKit.framework/Headers/UIView.h 600 | 601 | 602 | 603 | UIViewController 604 | 605 | IBFrameworkSource 606 | UIKit.framework/Headers/UINavigationController.h 607 | 608 | 609 | 610 | UIViewController 611 | 612 | IBFrameworkSource 613 | UIKit.framework/Headers/UIPopoverController.h 614 | 615 | 616 | 617 | UIViewController 618 | 619 | IBFrameworkSource 620 | UIKit.framework/Headers/UISplitViewController.h 621 | 622 | 623 | 624 | UIViewController 625 | 626 | IBFrameworkSource 627 | UIKit.framework/Headers/UITabBarController.h 628 | 629 | 630 | 631 | UIViewController 632 | UIResponder 633 | 634 | IBFrameworkSource 635 | UIKit.framework/Headers/UIViewController.h 636 | 637 | 638 | 639 | 640 | 0 641 | IBCocoaTouchFramework 642 | 643 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 644 | 645 | 646 | 647 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 648 | 649 | 650 | YES 651 | SMGeocoderApp.xcodeproj 652 | 3 653 | 132 654 | 655 | 656 | -------------------------------------------------------------------------------- /Demo/SVGeocoder_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SMGeocoderApp' target in the 'SMGeocoderApp' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SMGeocoderApp 4 | // 5 | // Created by Sam Vermette on 11.02.11. 6 | // Copyright 2011 Sam Vermette. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | @autoreleasepool { 14 | int retVal = UIApplicationMain(argc, argv, nil, nil); 15 | return retVal; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Sam Vermette 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | A different license may apply to other software included in this package, 25 | including John Engelhart's JSONKit class. Please consult their 26 | respective headers for the terms of their individual licenses. -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | __*Important note if your project doesn't use ARC*: you must add the @-fobjc-arc@ compiler flag to @SVGeocoder.m@ and @SVPlacemark.m@ in Target Settings > Build Phases > Compile Sources.__ 2 | 3 | h1. SVGeocoder 4 | 5 | SVGeocoder is a simple Cocoa wrapper for the "Google Geocoding Service":http://code.google.com/apis/maps/documentation/geocoding/. It allows you to quickly geocode and reverse-geocode addresses and coordinates. It is blocked-based, uses @NSURLConnection@, ARC, as well as @NSJSONSerialization@ to automatically parse JSON responses (making it only compatible with iOS 5+). Make sure you read the Google Geocoding Service "Terms of Service":http://code.google.com/apis/maps/terms.html#section_10_12 before using SVGeocoder. 6 | 7 | h2. Installation 8 | 9 | * Drag the @SVGeocoder/SVGeocoder@ folder into your project. 10 | * Add the *CoreLocation*, *MapKit* and frameworks to your project. 11 | 12 | h2. Usage 13 | 14 | h3. Using the Geocoding API 15 | 16 | In it's simplest form, geocoding an address is as simple as: 17 | 18 |
19 | [SVGeocoder geocode:addressField.text
20 |          completion:^(NSArray *placemarks, NSHTTPURLResponse *urlResponse, NSError *error) {
21 |              // do something with placemarks, handle errors
22 |          }];
23 | 
24 | 25 | Where @placemarks@ is an array of @SVPlacemark@ objects (see more about that below). 26 | 27 | Additionally, you can use Google Geocoding API's @region@ parameter to fine-tune your search: 28 | 29 |
30 | + (SVGeocoder*)geocode:(NSString *)address bounds:(MKCoordinateRegion)bounds completion:(SVGeocoderCompletionHandler)block;
31 | + (SVGeocoder*)geocode:(NSString *)address region:(CLRegion *)region completion:(SVGeocoderCompletionHandler)block;
32 | 
33 | 34 | h3. Using the Reverse Geocoding API 35 | 36 |
37 | [SVGeocoder reverseGeocode:CLLocationCoordinate2DMake(45.53264, -73.60518)
38 |                 completion:^(NSArray *placemarks, NSHTTPURLResponse *urlResponse, NSError *error) {
39 |                     // do something with placemarks, handle errors
40 |                 }];
41 | 
42 | 43 | h2. About the SVPlacemark object 44 | 45 | SVPlacemark is now a simple NSObject. Here's a sample placemark returned for string "3456 Saint-Denis, Montreal": 46 | 47 |
48 | {
49 |     ISOcountryCode = CA;
50 |     administrativeArea = Quebec;
51 |     coordinate = "45.517363, -73.568376";
52 |     country = Canada;
53 |     formattedAddress = "3456 Rue Saint-Denis, Montreal, QC H2X 3L1, Canada";
54 |     locality = Montreal;
55 |     postalCode = "H2X 3L1";
56 |     subAdministrativeArea = "Communaut\U00e9-Urbaine-de-Montr\U00e9al";
57 |     subLocality = "Le Plateau-Mont-Royal";
58 |     subThoroughfare = 3456;
59 |     thoroughfare = "Rue Saint-Denis";
60 | }
61 | 
62 | 63 | There's also a @region@ (@MKCoordinateRegion@) property in case the returned placemark isn't a pinned location, and a @location@ (@CLLocation@) convenience property. 64 | 65 | h2. Google Maps API Key 66 | 67 | You can include a Google Maps API Key by setting it before every request. If the key is not used the request will not be authenticated and request limits may apply. 68 | 69 | ATTENTION: You should generate a "browser key" (without any referrer) on Google API Console to use SVGecoder this way. iOS keys won't work as they are used in the official Google SDKs only, and they use the bundle identifier to validate the request. 70 | 71 |
72 | [SVGeocoder setGoogleMapsAPIKey:@"KEY"];
73 | 
74 | 75 | h2. Credits 76 | 77 | SVGeocoder is brought to you by "Sam Vermette":http://samvermette.com and "contributors to the project":https://github.com/samvermette/SVGeocoder/contributors. If you have feature suggestions or bug reports, feel free to help out by sending pull requests or by "creating new issues":https://github.com/samvermette/SVGeocoder/issues/new. If you're using SVGeocoder in your project, attribution would be nice. -------------------------------------------------------------------------------- /SVGeocoder.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'SVGeocoder' 3 | s.version = '0.3' 4 | s.license = 'MIT' 5 | s.platform = :ios 6 | s.summary = 'Simple Cocoa wrapper for the Google Geocoding Service.' 7 | s.homepage = 'https://github.com/samvermette/SVGeocoder' 8 | s.author = { 'Sam Vermette' => 'hello@samvermette.com' } 9 | s.source = { :git => 'https://github.com/samvermette/SVGeocoder.git', :tag => s.version.to_s } 10 | s.source_files = 'SVGeocoder/*.{h,m}' 11 | s.frameworks = 'MapKit', 'CoreLocation' 12 | s.preserve_paths = 'Demo' 13 | s.requires_arc = true 14 | end 15 | -------------------------------------------------------------------------------- /SVGeocoder/SVGeocoder.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVGeocoder.h 3 | // 4 | // Created by Sam Vermette on 07.02.11. 5 | // Copyright 2011 samvermette.com. All rights reserved. 6 | // 7 | // https://github.com/samvermette/SVGeocoder 8 | // http://code.google.com/apis/maps/documentation/geocoding/ 9 | // 10 | 11 | #import 12 | #import 13 | 14 | #import "SVPlacemark.h" 15 | 16 | #define SVGeocoderComponentRoute @"route" 17 | #define SVGeocoderComponentLocality @"locality" 18 | #define SVGeocoderAdministrativeArea @"administrative_area" 19 | #define SVGeocoderPostalCode @"postal_code" 20 | #define SVGeocoderCountry @"country" 21 | 22 | typedef enum { 23 | SVGeocoderZeroResultsError = 1, 24 | SVGeocoderOverQueryLimitError, 25 | SVGeocoderRequestDeniedError, 26 | SVGeocoderInvalidRequestError, 27 | SVGeocoderJSONParsingError 28 | } SVGecoderError; 29 | 30 | 31 | typedef void (^SVGeocoderCompletionHandler)(NSArray *placemarks, NSHTTPURLResponse *urlResponse, NSError *error); 32 | 33 | @interface SVGeocoder : NSOperation 34 | 35 | // Set static Google Maps API Key for all requests. 36 | // The key will be included in the request if it's 37 | // not nil. 38 | + (void)setGoogleMapsAPIKey:(NSString*)key; 39 | + (void)setGoogleMapsAPIURL:(NSString*)url; 40 | 41 | + (SVGeocoder*)geocode:(NSString *)address completion:(SVGeocoderCompletionHandler)block; 42 | 43 | + (SVGeocoder*)geocode:(NSString *)address region:(CLRegion *)region completion:(SVGeocoderCompletionHandler)block; 44 | + (SVGeocoder*)geocode:(NSString *)address components:(NSDictionary *)components completion:(SVGeocoderCompletionHandler)block; 45 | + (SVGeocoder*)geocode:(NSString *)address region:(CLRegion *)region components:(NSDictionary *)components completion:(SVGeocoderCompletionHandler)block; 46 | 47 | + (SVGeocoder*)reverseGeocode:(CLLocationCoordinate2D)coordinate completion:(SVGeocoderCompletionHandler)block; 48 | 49 | - (SVGeocoder*)initWithAddress:(NSString *)address completion:(SVGeocoderCompletionHandler)block; 50 | 51 | - (SVGeocoder*)initWithAddress:(NSString *)address region:(CLRegion *)region completion:(SVGeocoderCompletionHandler)block; 52 | - (SVGeocoder*)initWithAddress:(NSString *)address components:(NSDictionary *)components completion:(SVGeocoderCompletionHandler)block; 53 | - (SVGeocoder*)initWithAddress:(NSString *)address region:(CLRegion *)region components:(NSDictionary *)components completion:(SVGeocoderCompletionHandler)block; 54 | 55 | 56 | - (SVGeocoder*)initWithCoordinate:(CLLocationCoordinate2D)coordinate completion:(SVGeocoderCompletionHandler)block; 57 | 58 | - (void)start; 59 | 60 | - (void)cancel; 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /SVGeocoder/SVGeocoder.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVGeocoder.m 3 | // 4 | // Created by Sam Vermette on 07.02.11. 5 | // Copyright 2011 samvermette.com. All rights reserved. 6 | // 7 | // https://github.com/samvermette/SVGeocoder 8 | // http://code.google.com/apis/maps/documentation/geocoding/ 9 | // 10 | 11 | #import "SVGeocoder.h" 12 | #import 13 | 14 | #define kSVGeocoderTimeoutInterval 20 15 | 16 | enum { 17 | SVGeocoderStateReady = 0, 18 | SVGeocoderStateExecuting, 19 | SVGeocoderStateFinished 20 | }; 21 | 22 | typedef NSUInteger SVGeocoderState; 23 | static NSString *googleMapsAPIKey; 24 | static NSString *googleMapsAPIURL; 25 | 26 | @interface NSString (URLEncoding) 27 | - (NSString*)encodedURLParameterString; 28 | @end 29 | 30 | 31 | @interface SVGeocoder () 32 | 33 | @property (nonatomic, strong) NSMutableURLRequest *operationRequest; 34 | @property (nonatomic, strong) NSMutableData *operationData; 35 | @property (nonatomic, strong) NSURLConnection *operationConnection; 36 | @property (nonatomic, strong) NSHTTPURLResponse *operationURLResponse; 37 | 38 | @property (nonatomic, copy) SVGeocoderCompletionHandler operationCompletionBlock; 39 | @property (nonatomic, readwrite) SVGeocoderState state; 40 | @property (nonatomic, strong) NSString *requestPath; 41 | @property (nonatomic, strong) NSTimer *timeoutTimer; // see http://stackoverflow.com/questions/2736967 42 | 43 | - (SVGeocoder*)initWithParameters:(NSMutableDictionary*)parameters completion:(SVGeocoderCompletionHandler)block; 44 | 45 | - (void)addParametersToRequest:(NSMutableDictionary*)parameters; 46 | 47 | - (void)finish; 48 | - (NSString*)createComponentsStringFromDictionary:(NSDictionary *)components; 49 | - (NSString*)createBoundsStringFromRegion:(CLRegion *)region; 50 | 51 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error; 52 | 53 | - (void)callCompletionBlockWithResponse:(id)response error:(NSError *)error; 54 | 55 | @end 56 | 57 | @implementation SVGeocoder 58 | 59 | // private properties 60 | @synthesize operationRequest, operationData, operationConnection, operationURLResponse, state; 61 | @synthesize operationCompletionBlock, timeoutTimer; 62 | 63 | #pragma mark - 64 | 65 | - (void)dealloc { 66 | [operationConnection cancel]; 67 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE && !TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR 68 | [super dealloc]; 69 | #endif 70 | 71 | } 72 | 73 | #pragma mark - Convenience Initializers 74 | 75 | + (SVGeocoder *)geocode:(NSString *)address completion:(SVGeocoderCompletionHandler)block { 76 | SVGeocoder *geocoder = [[self alloc] initWithAddress:address completion:block]; 77 | [geocoder start]; 78 | return geocoder; 79 | } 80 | 81 | + (SVGeocoder *)geocode:(NSString *)address region:(CLRegion *)region completion:(SVGeocoderCompletionHandler)block { 82 | SVGeocoder *geocoder = [[self alloc] initWithAddress:address region:region completion:block]; 83 | [geocoder start]; 84 | return geocoder; 85 | } 86 | 87 | + (SVGeocoder*)geocode:(NSString *)address components:(NSDictionary *)components completion:(SVGeocoderCompletionHandler)block { 88 | SVGeocoder *geocoder = [[self alloc] initWithAddress:address components:components completion:block]; 89 | [geocoder start]; 90 | return geocoder; 91 | } 92 | 93 | + (SVGeocoder*)geocode:(NSString *)address region:(CLRegion *)region components:(NSDictionary *)components completion:(SVGeocoderCompletionHandler)block { 94 | SVGeocoder *geocoder = [[self alloc] initWithAddress:address region:region components:components completion:block]; 95 | [geocoder start]; 96 | return geocoder; 97 | } 98 | 99 | + (SVGeocoder *)reverseGeocode:(CLLocationCoordinate2D)coordinate completion:(SVGeocoderCompletionHandler)block { 100 | SVGeocoder *geocoder = [[self alloc] initWithCoordinate:coordinate completion:block]; 101 | [geocoder start]; 102 | return geocoder; 103 | } 104 | 105 | + (void)setGoogleMapsAPIKey:(NSString *)key { 106 | 107 | googleMapsAPIKey = [key copy]; 108 | 109 | } 110 | 111 | + (void)setGoogleMapsAPIURL:(NSString *)url { 112 | 113 | googleMapsAPIURL = [url copy]; 114 | 115 | } 116 | 117 | + (void)load { 118 | 119 | googleMapsAPIURL = @"https://maps.googleapis.com/maps/api/geocode/json"; 120 | 121 | } 122 | 123 | #pragma mark - Public Initializers 124 | 125 | - (SVGeocoder*)initWithCoordinate:(CLLocationCoordinate2D)coordinate completion:(SVGeocoderCompletionHandler)block { 126 | NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys: 127 | [NSString stringWithFormat:@"%f,%f", coordinate.latitude, coordinate.longitude], @"latlng", nil]; 128 | 129 | return [self initWithParameters:parameters completion:block]; 130 | } 131 | 132 | 133 | - (SVGeocoder*)initWithAddress:(NSString*)address completion:(SVGeocoderCompletionHandler)block { 134 | NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys: 135 | address, @"address", nil]; 136 | 137 | return [self initWithParameters:parameters completion:block]; 138 | } 139 | 140 | - (SVGeocoder*)initWithAddress:(NSString *)address region:(CLRegion *)region completion:(SVGeocoderCompletionHandler)block { 141 | NSString *bounds = [self createBoundsStringFromRegion:region]; 142 | 143 | NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys: 144 | address, @"address", 145 | bounds, @"bounds", nil]; 146 | 147 | return [self initWithParameters:parameters completion:block]; 148 | } 149 | 150 | - (SVGeocoder*)initWithAddress:(NSString *)address components:(NSDictionary *)components completion:(SVGeocoderCompletionHandler)block { 151 | NSString *componentsValue = [self createComponentsStringFromDictionary:components]; 152 | 153 | NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys: 154 | address, @"address", 155 | componentsValue, @"components", nil]; 156 | 157 | return [self initWithParameters:parameters completion:block]; 158 | } 159 | 160 | - (SVGeocoder*)initWithAddress:(NSString *)address region:(CLRegion *)region components:(NSDictionary *)components completion:(SVGeocoderCompletionHandler)block { 161 | NSString *bounds = [self createBoundsStringFromRegion:region]; 162 | NSString *componentsValue = [self createComponentsStringFromDictionary:components]; 163 | 164 | NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys: 165 | address, @"address", 166 | bounds, @"bounds", 167 | componentsValue, @"components", nil]; 168 | 169 | return [self initWithParameters:parameters completion:block]; 170 | } 171 | 172 | #pragma mark - Private Utility Methods 173 | 174 | - (SVGeocoder*)initWithParameters:(NSMutableDictionary*)parameters completion:(SVGeocoderCompletionHandler)block { 175 | self = [super init]; 176 | self.operationCompletionBlock = block; 177 | self.operationRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:googleMapsAPIURL]]; 178 | [self.operationRequest setTimeoutInterval:kSVGeocoderTimeoutInterval]; 179 | 180 | [parameters setValue:@"true" forKey:@"sensor"]; 181 | [parameters setValue:[NSLocale preferredLanguages][0] forKey:@"language"]; 182 | 183 | if (googleMapsAPIKey) { 184 | [parameters setValue:googleMapsAPIKey forKey:@"key"]; 185 | } 186 | 187 | [self addParametersToRequest:parameters]; 188 | 189 | self.state = SVGeocoderStateReady; 190 | 191 | return self; 192 | } 193 | 194 | - (void)addParametersToRequest:(NSMutableDictionary*)parameters { 195 | 196 | NSMutableArray *paramStringsArray = [NSMutableArray arrayWithCapacity:[[parameters allKeys] count]]; 197 | 198 | for(NSString *key in [parameters allKeys]) { 199 | NSObject *paramValue = [parameters valueForKey:key]; 200 | if ([paramValue isKindOfClass:[NSString class]]) { 201 | [paramStringsArray addObject:[NSString stringWithFormat:@"%@=%@", key, [(NSString *)paramValue encodedURLParameterString]]]; 202 | } else { 203 | [paramStringsArray addObject:[NSString stringWithFormat:@"%@=%@", key, paramValue]]; 204 | } 205 | } 206 | 207 | NSString *paramsString = [paramStringsArray componentsJoinedByString:@"&"]; 208 | NSString *baseAddress = self.operationRequest.URL.absoluteString; 209 | baseAddress = [baseAddress stringByAppendingFormat:@"?%@", paramsString]; 210 | [self.operationRequest setURL:[NSURL URLWithString:baseAddress]]; 211 | } 212 | 213 | - (void)setTimeoutTimer:(NSTimer *)newTimer { 214 | 215 | if(timeoutTimer) 216 | [timeoutTimer invalidate], timeoutTimer = nil; 217 | 218 | if(newTimer) 219 | timeoutTimer = newTimer; 220 | } 221 | 222 | - (NSString*)createComponentsStringFromDictionary:(NSDictionary *)components { 223 | NSMutableArray *preparedComponents = [NSMutableArray new]; 224 | 225 | [components enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSString* value, BOOL *stop) { 226 | NSString *component = [NSString stringWithFormat:@"%@:%@", key, value]; 227 | [preparedComponents addObject:component]; 228 | }]; 229 | 230 | NSString *componentsValue = [preparedComponents componentsJoinedByString:@"|"]; 231 | 232 | return componentsValue; 233 | } 234 | 235 | - (NSString*)createBoundsStringFromRegion:(CLRegion *)region { 236 | MKCoordinateRegion coordinateRegion = MKCoordinateRegionMakeWithDistance(region.center, region.radius, region.radius); 237 | 238 | NSString *bounds = [NSString stringWithFormat:@"%f,%f|%f,%f", 239 | coordinateRegion.center.latitude-(coordinateRegion.span.latitudeDelta/2.0), 240 | coordinateRegion.center.longitude-(coordinateRegion.span.longitudeDelta/2.0), 241 | coordinateRegion.center.latitude+(coordinateRegion.span.latitudeDelta/2.0), 242 | coordinateRegion.center.longitude+(coordinateRegion.span.longitudeDelta/2.0)]; 243 | 244 | return bounds; 245 | } 246 | 247 | #pragma mark - NSOperation methods 248 | 249 | - (void)start { 250 | 251 | if(self.isCancelled) { 252 | [self finish]; 253 | return; 254 | } 255 | 256 | if(![NSThread isMainThread]) { // NSOperationQueue calls start from a bg thread (through GCD), but NSURLConnection already does that by itself 257 | [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO]; 258 | return; 259 | } 260 | 261 | [self willChangeValueForKey:@"isExecuting"]; 262 | self.state = SVGeocoderStateExecuting; 263 | [self didChangeValueForKey:@"isExecuting"]; 264 | 265 | self.operationData = [[NSMutableData alloc] init]; 266 | self.timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:kSVGeocoderTimeoutInterval target:self selector:@selector(requestTimeout) userInfo:nil repeats:NO]; 267 | 268 | self.operationConnection = [[NSURLConnection alloc] initWithRequest:self.operationRequest delegate:self startImmediately:NO]; 269 | [self.operationConnection start]; 270 | 271 | #if !(defined SVHTTPREQUEST_DISABLE_LOGGING) 272 | NSLog(@"[%@] %@", self.operationRequest.HTTPMethod, self.operationRequest.URL.absoluteString); 273 | #endif 274 | } 275 | 276 | - (void)finish { 277 | [self.operationConnection cancel]; 278 | operationConnection = nil; 279 | 280 | [self willChangeValueForKey:@"isExecuting"]; 281 | [self willChangeValueForKey:@"isFinished"]; 282 | self.state = SVGeocoderStateFinished; 283 | [self didChangeValueForKey:@"isExecuting"]; 284 | [self didChangeValueForKey:@"isFinished"]; 285 | } 286 | 287 | - (void)cancel { 288 | if([self isFinished]) 289 | return; 290 | 291 | [super cancel]; 292 | [self callCompletionBlockWithResponse:nil error:nil]; 293 | } 294 | 295 | - (BOOL)isConcurrent { 296 | return YES; 297 | } 298 | 299 | - (BOOL)isFinished { 300 | return self.state == SVGeocoderStateFinished; 301 | } 302 | 303 | - (BOOL)isExecuting { 304 | return self.state == SVGeocoderStateExecuting; 305 | } 306 | 307 | - (SVGeocoderState)state { 308 | @synchronized(self) { 309 | return state; 310 | } 311 | } 312 | 313 | - (void)setState:(SVGeocoderState)newState { 314 | @synchronized(self) { 315 | [self willChangeValueForKey:@"state"]; 316 | state = newState; 317 | [self didChangeValueForKey:@"state"]; 318 | } 319 | } 320 | 321 | 322 | #pragma mark - 323 | #pragma mark NSURLConnectionDelegate 324 | 325 | - (void)requestTimeout { 326 | NSURL *failingURL = self.operationRequest.URL; 327 | 328 | NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: 329 | @"The operation timed out.", NSLocalizedDescriptionKey, 330 | failingURL, NSURLErrorFailingURLErrorKey, 331 | failingURL.absoluteString, NSURLErrorFailingURLStringErrorKey, nil]; 332 | 333 | NSError *timeoutError = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:userInfo]; 334 | [self connection:nil didFailWithError:timeoutError]; 335 | } 336 | 337 | 338 | - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 339 | self.operationURLResponse = (NSHTTPURLResponse*)response; 340 | } 341 | 342 | 343 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 344 | [self.operationData appendData:data]; 345 | } 346 | 347 | 348 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection { 349 | NSMutableArray *placemarks = nil; 350 | NSError *error = nil; 351 | 352 | if ([[operationURLResponse MIMEType] isEqualToString:@"application/json"]) { 353 | if(self.operationData && self.operationData.length > 0) { 354 | id response = [NSData dataWithData:self.operationData]; 355 | NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingAllowFragments error:&error]; 356 | NSArray *results = [jsonObject objectForKey:@"results"]; 357 | NSString *status = [jsonObject valueForKey:@"status"]; 358 | 359 | if(results) 360 | placemarks = [NSMutableArray arrayWithCapacity:results.count]; 361 | 362 | if(results.count > 0) { 363 | [results enumerateObjectsUsingBlock:^(NSDictionary *result, NSUInteger idx, BOOL *stop) { 364 | SVPlacemark *placemark = [[SVPlacemark alloc] initWithDictionary:result]; 365 | [placemarks addObject:placemark]; 366 | }]; 367 | } 368 | else { 369 | if ([status isEqualToString:@"ZERO_RESULTS"]) { 370 | NSDictionary *userinfo = [NSDictionary dictionaryWithObjectsAndKeys:@"Zero results returned", NSLocalizedDescriptionKey, nil]; 371 | error = [NSError errorWithDomain:@"SVGeocoderErrorDomain" code:SVGeocoderZeroResultsError userInfo:userinfo]; 372 | } 373 | 374 | else if ([status isEqualToString:@"OVER_QUERY_LIMIT"]) { 375 | NSDictionary *userinfo = [NSDictionary dictionaryWithObjectsAndKeys:@"Currently rate limited. Too many queries in a short time. (Over Quota)", NSLocalizedDescriptionKey, nil]; 376 | error = [NSError errorWithDomain:@"SVGeocoderErrorDomain" code:SVGeocoderOverQueryLimitError userInfo:userinfo]; 377 | } 378 | 379 | else if ([status isEqualToString:@"REQUEST_DENIED"]) { 380 | NSDictionary *userinfo = [NSDictionary dictionaryWithObjectsAndKeys:@"Request was denied. Did you remember to add the \"sensor\" parameter?", NSLocalizedDescriptionKey, nil]; 381 | error = [NSError errorWithDomain:@"SVGeocoderErrorDomain" code:SVGeocoderRequestDeniedError userInfo:userinfo]; 382 | } 383 | 384 | else if ([status isEqualToString:@"INVALID_REQUEST"]) { 385 | NSDictionary *userinfo = [NSDictionary dictionaryWithObjectsAndKeys:@"The request was invalid. Was the \"address\" or \"latlng\" missing?", NSLocalizedDescriptionKey, nil]; 386 | error = [NSError errorWithDomain:@"SVGeocoderErrorDomain" code:SVGeocoderInvalidRequestError userInfo:userinfo]; 387 | } 388 | } 389 | } 390 | } 391 | 392 | [self callCompletionBlockWithResponse:placemarks error:error]; 393 | } 394 | 395 | 396 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 397 | [self callCompletionBlockWithResponse:nil error:error]; 398 | } 399 | 400 | - (void)callCompletionBlockWithResponse:(id)response error:(NSError *)error { 401 | self.timeoutTimer = nil; 402 | 403 | dispatch_async(dispatch_get_main_queue(), ^{ 404 | NSError *serverError = error; 405 | 406 | if(!serverError && self.operationURLResponse.statusCode == 500) { 407 | serverError = [NSError errorWithDomain:NSURLErrorDomain 408 | code:NSURLErrorBadServerResponse 409 | userInfo:[NSDictionary dictionaryWithObjectsAndKeys: 410 | @"Bad Server Response.", NSLocalizedDescriptionKey, 411 | self.operationRequest.URL, NSURLErrorFailingURLErrorKey, 412 | self.operationRequest.URL.absoluteString, NSURLErrorFailingURLStringErrorKey, nil]]; 413 | } 414 | 415 | if(self.operationCompletionBlock && !self.isCancelled) 416 | self.operationCompletionBlock([response copy], self.operationURLResponse, serverError); 417 | 418 | [self finish]; 419 | }); 420 | } 421 | 422 | 423 | @end 424 | 425 | 426 | #pragma mark - 427 | 428 | @implementation NSString (URLEncoding) 429 | 430 | - (NSString*)encodedURLParameterString { 431 | NSString *result = (NSString*)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 432 | (__bridge CFStringRef)self, 433 | NULL, 434 | CFSTR(":/=,!$&'()*+;[]@#?|"), 435 | kCFStringEncodingUTF8)); 436 | return result; 437 | } 438 | 439 | @end 440 | -------------------------------------------------------------------------------- /SVGeocoder/SVPlacemark.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVPlacemark.h 3 | // SVGeocoder 4 | // 5 | // Created by Sam Vermette on 01.05.11. 6 | // Copyright 2011 samvermette.com. All rights reserved. 7 | // 8 | // https://github.com/samvermette/SVGeocoder 9 | // 10 | 11 | #import 12 | #import 13 | 14 | @interface SVPlacemark : NSObject 15 | 16 | - (id)initWithDictionary:(NSDictionary*)dictionary; 17 | 18 | @property (nonatomic, strong, readonly) NSString *name; 19 | @property (nonatomic, strong, readonly) NSString *formattedAddress; 20 | @property (nonatomic, strong, readonly) NSString *subThoroughfare; 21 | @property (nonatomic, strong, readonly) NSString *thoroughfare; 22 | @property (nonatomic, strong, readonly) NSString *subLocality; 23 | @property (nonatomic, strong, readonly) NSString *locality; 24 | @property (nonatomic, strong, readonly) NSString *subAdministrativeArea; 25 | @property (nonatomic, strong, readonly) NSString *administrativeArea; 26 | @property (nonatomic, strong, readonly) NSString *administrativeAreaCode; 27 | @property (nonatomic, strong, readonly) NSString *postalCode; 28 | @property (nonatomic, strong, readonly) NSString *country; 29 | @property (nonatomic, strong, readonly) NSString *ISOcountryCode; 30 | 31 | @property (nonatomic, readonly) CLLocationCoordinate2D coordinate; 32 | @property (nonatomic, readonly) MKCoordinateRegion region; 33 | @property (nonatomic, strong, readonly) CLLocation *location; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /SVGeocoder/SVPlacemark.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVPlacemark.m 3 | // SVGeocoder 4 | // 5 | // Created by Sam Vermette on 01.05.11. 6 | // Copyright 2011 samvermette.com. All rights reserved. 7 | // 8 | // https://github.com/samvermette/SVGeocoder 9 | // 10 | 11 | #import "SVPlacemark.h" 12 | 13 | @interface SVPlacemark () 14 | 15 | @property (nonatomic, strong, readwrite) NSString *name; 16 | @property (nonatomic, strong, readwrite) NSString *formattedAddress; 17 | @property (nonatomic, strong, readwrite) NSString *subThoroughfare; 18 | @property (nonatomic, strong, readwrite) NSString *thoroughfare; 19 | @property (nonatomic, strong, readwrite) NSString *subLocality; 20 | @property (nonatomic, strong, readwrite) NSString *locality; 21 | @property (nonatomic, strong, readwrite) NSString *subAdministrativeArea; 22 | @property (nonatomic, strong, readwrite) NSString *administrativeArea; 23 | @property (nonatomic, strong, readwrite) NSString *administrativeAreaCode; 24 | @property (nonatomic, strong, readwrite) NSString *postalCode; 25 | @property (nonatomic, strong, readwrite) NSString *country; 26 | @property (nonatomic, strong, readwrite) NSString *ISOcountryCode; 27 | 28 | @property (nonatomic, readwrite) CLLocationCoordinate2D coordinate; 29 | @property (nonatomic, readwrite) MKCoordinateRegion region; 30 | @property (nonatomic, strong, readwrite) CLLocation *location; 31 | 32 | @end 33 | 34 | 35 | @implementation SVPlacemark 36 | 37 | @synthesize formattedAddress, subThoroughfare, thoroughfare, subLocality, locality, subAdministrativeArea, administrativeArea, administrativeAreaCode, postalCode, country, ISOcountryCode, coordinate, location, region; 38 | 39 | - (id)initWithDictionary:(NSDictionary *)result { 40 | 41 | if(self = [super init]) { 42 | self.name = [result objectForKey:@"name"]; 43 | self.formattedAddress = [result objectForKey:@"formatted_address"]; 44 | 45 | NSArray *addressComponents = [result objectForKey:@"address_components"]; 46 | 47 | [addressComponents enumerateObjectsUsingBlock:^(NSDictionary *component, NSUInteger idx, BOOL *stopAddress) { 48 | NSArray *types = [component objectForKey:@"types"]; 49 | 50 | if([types containsObject:@"street_number"]) 51 | self.subThoroughfare = [component objectForKey:@"long_name"]; 52 | 53 | if([types containsObject:@"route"]) 54 | self.thoroughfare = [component objectForKey:@"long_name"]; 55 | 56 | if([types containsObject:@"administrative_area_level_3"] || [types containsObject:@"sublocality"] || [types containsObject:@"neighborhood"]) 57 | self.subLocality = [component objectForKey:@"long_name"]; 58 | 59 | if([types containsObject:@"locality"]) 60 | self.locality = [component objectForKey:@"long_name"]; 61 | 62 | if([types containsObject:@"administrative_area_level_2"]) 63 | self.subAdministrativeArea = [component objectForKey:@"long_name"]; 64 | 65 | if([types containsObject:@"administrative_area_level_1"]) { 66 | self.administrativeArea = [component objectForKey:@"long_name"]; 67 | self.administrativeAreaCode = [component objectForKey:@"short_name"]; 68 | } 69 | 70 | if([types containsObject:@"country"]) { 71 | self.country = [component objectForKey:@"long_name"]; 72 | self.ISOcountryCode = [component objectForKey:@"short_name"]; 73 | } 74 | 75 | if([types containsObject:@"postal_code"]) 76 | self.postalCode = [component objectForKey:@"long_name"]; 77 | 78 | }]; 79 | 80 | NSDictionary *locationDict = [[result objectForKey:@"geometry"] objectForKey:@"location"]; 81 | NSDictionary *boundsDict = [[result objectForKey:@"geometry"] objectForKey:@"bounds"]; 82 | 83 | CLLocationDegrees lat = [[locationDict objectForKey:@"lat"] doubleValue]; 84 | CLLocationDegrees lng = [[locationDict objectForKey:@"lng"] doubleValue]; 85 | self.coordinate = CLLocationCoordinate2DMake(lat, lng); 86 | self.location = [[CLLocation alloc] initWithLatitude:lat longitude:lng]; 87 | 88 | NSDictionary *northEastDict = [boundsDict objectForKey:@"northeast"]; 89 | NSDictionary *southWestDict = [boundsDict objectForKey:@"southwest"]; 90 | CLLocationDegrees northEastLatitude = [[northEastDict objectForKey:@"lat"] doubleValue]; 91 | CLLocationDegrees southWestLatitude = [[southWestDict objectForKey:@"lat"] doubleValue]; 92 | CLLocationDegrees latitudeDelta = fabs(northEastLatitude - southWestLatitude); 93 | CLLocationDegrees northEastLongitude = [[northEastDict objectForKey:@"lng"] doubleValue]; 94 | CLLocationDegrees southWestLongitude = [[southWestDict objectForKey:@"lng"] doubleValue]; 95 | CLLocationDegrees longitudeDelta = fabs(northEastLongitude - southWestLongitude); 96 | MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta); 97 | self.region = MKCoordinateRegionMake(self.location.coordinate, span); 98 | } 99 | 100 | return self; 101 | } 102 | 103 | 104 | - (NSString*)description { 105 | NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: 106 | formattedAddress, @"formattedAddress", 107 | subThoroughfare?subThoroughfare:[NSNull null], @"subThoroughfare", 108 | thoroughfare?thoroughfare:[NSNull null], @"thoroughfare", 109 | subLocality?subLocality:[NSNull null], @"subLocality", 110 | locality?locality:[NSNull null], @"locality", 111 | subAdministrativeArea?subAdministrativeArea:[NSNull null], @"subAdministrativeArea", 112 | administrativeArea?administrativeArea:[NSNull null], @"administrativeArea", 113 | postalCode?postalCode:[NSNull null], @"postalCode", 114 | country?country:[NSNull null], @"country", 115 | ISOcountryCode?ISOcountryCode:[NSNull null], @"ISOcountryCode", 116 | [NSString stringWithFormat:@"%f, %f", self.coordinate.latitude, self.coordinate.longitude], @"coordinate", 117 | nil]; 118 | 119 | return [dict description]; 120 | } 121 | 122 | @end 123 | --------------------------------------------------------------------------------