A locator allows you to geocode addresses and reverse geocode locations. Geocoding an address involves finding a matching location for it on a map. Reverse-geocoding is the opposite; it involves finding corresponding address candidates for a given location.

The locator requires either an address locator dataset on the device, or access to a remote ArcGIS Geocoding Service. When using a local dataset, geocoding and reverse-geocoding operations can be performed wholly on the device even when the device has no network connectivity. On the other hand, using remote services requires the device to have a network connection.

Address locator datasets

An address locator contains a combination of location-specific attributes and certain style-specific guidelines that allow it to interpret a particular type of address input, relate it with the predefined address attributes, and deliver a certain type of output back to the user interface. Address locators comprise a set of *.loc, *.loc.xml, *.lox, and *.locb files on disk. These files represent GIS datasets and other reference data to find addresses and locations. These files also contain information about the address style used to parse addresses and standardize them into well-structured address components.

There are 2 ways to make an address locator dataset available on an iOS device .

  • Include it within the application
  • Copy it over to the application's shared folder using iTunes

These options are described in more detail later in this topic.

Geocode Services

Geocode services are based on address locator datasets. They can be hosted in Esri's cloud platform, ArcGIS Online, or can be published on your own on-premise ArcGIS servers. These services provide a REST API for clients such as mobile and web applications.

Learn more about Geocode services.

Creating the locator

Using address locator included within the application

To include an address locator dataset in your application, you need to add the *.loc, *.loc.xml, *.locb, and *.lox files to your application's XCode project. When you subsequently build your application, XCode will copy the dataset to the application bundle. When a user installs your application on their device, either through the App Store or through ITunes, the dataset is installed as part of the application. The following image shows a network dataset added to an XCode project.

To instantiate a locator using the dataset bundled with the application, you need to provide the name of the *.loc file . The following code snippet shows how to create a locator for the dataset used in the image above.

NSError* error = nil;
AGSLocator* locator = [AGSLocator locatorName:@"SanDiegoLocator" error:&error];

Using address locator copied through iTunes file sharing

In this scenario, the dataset is not bundled within the application. Rather, you need to manually copy the dataset to the application's shared folder on the device using iTunes.

Learn more about iTunes file sharing


To enable file sharing for your application, you must set the UIFileSharingEnabled key (displayed as "Application supports iTunes file sharing") to true in the application's Info.plist file. Any files copied through file sharing are made available in the Documents directory of the application. For more information about the iOS file system, see the Apple File System Programming Guide.

To instantiate a locator using a dataset copied through iTunes file sharing, you need to provide the full path to the *.loc file. The following code snippet shows how to create a locator for the address locator dataset used in the image above.

NSError* error = nil;
NSString* documentsDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUSerDomainMask, YES)[0];
NSString* fullPath = [documentsDir stringByAppendingPathComponent:@"SanDiegoLocator.loc"];
AGSLocator* locator = [AGSLocator locatorWithPath:fullPath error:&error];

Using remote Geocode services

To instantiate locator using a remote service, you need to provide a URL to REST endpoing that represents a Geocode service. If the web service is secured, you also need to provide the credentials that can be used to access the service. The following code snippet shows how to create a locator for the ESRI_Geocode_USA service on ArcGIS Online.

NSURL* url = [NSURL URLWithString: @"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Locators/ESRI_Geocode_USA/GeocodeServer"];
AGSLocator* locator = [[AGSLocator alloc] initWithURL: url];


When you create the locator, you need to ensure its memory does not get deallocated before it has a chance to execute. To do this, you need to retain the locator if you're using manual retain-release, or create a strong reference to it if you're using ARC. See Apple Memory Management Programming Guide for more information on how to manage object memory.

Geocoding an address

To find matching locations for an address, you must provide an NSDictionary object containing the address in a format expected by the service. The format is listed in the Address Fields section in the Services Directory. Only fields that are required must be specified. Others can be omitted.

Address Fields

For the service you’re using, you need to specify address, city, state and ZIP.

NSDictionary *address = [NSDictionary dictionaryWithObjectsAndKeys: @"380 New York St", @"Address", @"Redlands", @"City", @"CA", @"State", @"92373", @"Zip",  nil];

To geocode an intersection of two streets instead of a business or a home, you need to use a permitted connector to specify the streets. This connector is listed in the Locator Properties section of the Services Directory. The service you're using allows the use of the symbols &, |, or @ as connectors.

NSDictionary *address = [NSDictionary dictionaryWithObjectsAndKeys: @"New York St & State St", @"Address", @"Redlands", @"City", @"CA", @"State", @"92373", @"Zip",  nil];

You also need to specify which fields should be returned when a matching location is found. The fields available to you are listed in the Candidate Fields section of the Services Directory. If the address you’re geocoding is an intersection, use theIntersection Candidate Fields section instead.

Candidate fields
Intersection Candidate Fields

Services from ArcGIS 10 Server and later allow you to use the * wildcard to get all the fields. For earlier servers, you need to explicitly specify each field.

NSArray *outFields = [NSArray arrayWithObjects: @"Shape", @"Score", @"Match_addr", @"Side ", @"HouseNum", @"StreetName", @"StreetType", @"City","State", @"Zip", nil];

You can also optionally specify the output spatial reference. This is the spatial reference in which the matching locations should be returned to you. By default, the locations returned to you will have the same spatial reference as that of the service. By explicitly specifying a different spatial reference, the geocode service can re-project the locations so that you can easily display them on your map. This is useful, for example, when the geocode service uses a spatial reference that is different from the spatial reference of your map.

AGSSpatialReference* outSR = [AGSSpatialReference spatialReferenceWithWKID:4326 WKT:nil];
[locator locationsForAddress:address returnFields:outfields outSpatialReference:outSR];

Reverse geocoding a location

To find address candidates for a location, you need to provide a point representing the location. If the point does not have a spatial reference, the geocode service assumes it's in the spatial reference of the service. You also need to provide a maximum search distance (in meters) within which to search for address candidates from the given location. You can optionally specify an output spatial reference in which the address candidates should be returned.

AGSPoint* point = [AGSPoint pointWithX: -117.195681386 y: 34.057517097 spatialReference:[AGSSpatialReference spatialReferenceWithWKID:4326 WKT:nil]];
[locator addressForLocation:point maxSearchDistance:100];

Getting results and handling errors

The locator informs its delegate when operations complete successfully or when errors are encountered. To get results from the locator and to properly handle any errors, you must set one of your classes as the locator’s delegate. You do this by making your class (typically the view controller that uses the locator) adopt the AGSLocatorDelegate protocol.

@interface MyViewController : UIViewController <AGSLocatorDelegate> {  

An instance of your class must also be set as the locator’s delegate. This allows the locator to invoke methods on your class in response to operations that it performs.

locator.delegate = self;

Finally, your class must implement one or more methods defined in the protocol that pertain to the operation being performed. For geocoding operations, the delegate should implement the locator:operation:didFindLocationsForAddress: method to be informed when the operation finishes successfully. Results of the operation are passed to the delegate method as an array of AGSAddressCandidate objects.

- (void) locator:(AGSLocator*) locator operation:(NSOperation*) op didFindLocationsForAddress:(NSArray*) candidates {
   for (AGSAddressCandidate* candidate in candidates) {
     NSLog(@"Candidate : %@",candidate);  

To be informed of failure, the delegate should implement the locator:operation:didFailLocationsForAddress: method. The reason for failure is passed to the method as an NSError object.

- (void) locator:(AGSLocator*) locator operation:(NSOperation*) op didFailLocationsForAddress:(NSError*) error { 
   NSLog(@"Error: %@",error); 

If your delegate methods are not being invoked when the locator finishes execution, check to make sure that the locator is not getting deallocated before it finishes execution. You need to retain the locator if you're using manual retain-release, or create a strong reference to it if you're using ARC.

See also

Related topics