Skip To Content ArcGIS for Developers Sign In Dashboard


The geoprocessor allows you to perform geographic analysis and batch operations using geoprocessing tools and models on ArcGIS Server. These models and tools are exposed through geoprocessing services.

Geoprocessing allows you to automate and chain together GIS analysis and operations. You do this by creating custom tools and models with ArcGIS. A model generally consists of a series of tools in Esri's ArcToolbox, chained together in a logical way to accomplish a specific outcome. For example, a model might interpolate an elevation surface from a set of input spot heights, then create contours from that surface. Instead of individually executing the tools in sequence, you run the model. If you need to perform this operation on 100 datasets, you can automate the model to run 100 times. This makes geoprocessing both powerful and convenient.

ArcGIS Server geoprocessing services are accessible on the web as SOAP and REST web services. A geoprocessing service is a collection of one or more geoprocessing tasks. Each task is based on a geoprocessing model or a tool and performs a predefined function. When publishing the service, the administrator can allow the geoprocessing tasks to be invoked asynchronously or synchronously. The service will then either support a Submit Job operation or an Execute task operation, respectively. The latter is a blocking call and suitable for geoprocessing tasks that take only a short time to complete. The client waits until the operation is complete on the server. When the operation is complete, the client is given the results. The former is a non-blocking call and is suitable for long running geoprocessing tasks. It allows the client to do other things while the task is running on the server. The client can check back periodically to see if the job is finished, then get the results. The difference between these two modes is not so relevant for iOS developers working. Both the methods (executing a task and submitting a job) on the geoprocessor are asynchronous. As a developer, you are shielded from the asynchronous/synchronous nature of the geoprocessing task.

To successfully use the geoprocessor, you must know the following:

  • The URL of the geoprocessing service’s REST web service endpoint.
  • The geoprocessing task you want to execute and whether that task can be executed asynchronously or synchronously.
  • The inputs expected by the service’s task and the results that will be returned.

You can use the ArcGIS Server Services Directory to find these details about the service you want to use. If you're familiar with the ArcGIS Server REST API, you can invoke operations on the service directly from a browser using the Services Directory.

Creating a geoprocessor

To instantiate a geoprocessor, you need to provide a URL to a geoprocessing task in a geoprocessing service REST endpoint. This URL is usually of the form http://<server:port>/<instance>/services/<service>/GPServer/<task>.

If the web service is secured, you also need to provide the credentials that can be used to access the service. In this topic, you’ll use the Mailing List geoprocessing task from a sample server on ArcGIS Online. The task is available in both synchronous and asynchronous services –ESRI_CadastralData_PortlandSync and ESRI_CadastralData_Portland.

let url = NSURL(string: "")
let geoprocessor = AGSGeoprocessor(URL: url)

When you create the geoprocessor, 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 geprocessor if you're using manual retain-release, or create a strong reference to it if you're using ARC. See Apple's Memory Management Programming Guide for more information on how to manage object memory.

Preparing the input

Input to the geoprocessor is supplied as an array. The array contains values for parameters listed in the Parameters section of the Services Directory for the geoprocessing task. The section contains all the information needed to prepare the input.

Parameters section in Services Directory

Only input parameters (that is, parameters with Direction = esriGPParameterDirectionInput, need to be present in the array. Of these, some parameters are required (parameters with Type = esriGPParameterTypeRequired). These parameters must be specified. Others are optional (Type = esriGPParameterTypeOptional) and can be omitted.

Each parameter value is specified using an AGSGPParameterValue object. This object requires the parameter’s name, type, and value. The name and type information are available in the Service Directory. The value is an Objective-C object whose type is determined by the data type of the parameter. The following table provides a mapping between possible Parameter Data Types and their Objective-C counterparts:

Parameter data typeObjective-C type

























When the data type of the parameter is GPFeatureRecordSetLayer or GPRecordSet, the Default Value in the Services Directory gives clues about the fields and the geometry type of the corresponding AGSFeatureSet.

GPFeatureRecordSetLayer Parameter

For the geoprocessing task that you're using, you need to provide a parcel ID and a search distance as input parameters.

let parcel = AGSGPParameterValue(name: "Parcel_ID", type: .String, value: "1N1E34CC  -06600")
let distance = AGSGPParameterValue(name: "SearchDistance_ft", type: .Long, value: 100)

let params = [parcel, distance]

Executing a geoprocessing task synchronously

To execute a geoprocessing task, you need to provide an array of input parameters to the geoprocessor’s executeWithParameters: method.


Submitting a geoprocessing job for asynchronous execution

To submit a job, you need to provide the array of input parameters to the geoprocessor’s submitJobWithParameters: method. You can also specify how often you want the geoprocessor to check the status of the job. By default, the geoprocessor checks every 5 seconds, but you should use a higher interval if you know your geoprocessing task takes longer to complete.

geoprocessor.interval = 20

Getting results and handling errors

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

class MyViewController: UIViewController, AGSGeoprocessorDelegate {

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

geoprocessor.delegate = self

Finally, your class must implement one or more methods defined in the protocol that pertain to the operation being performed.


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

For synchronous task execution, you need to implement the geoprocessor:operation:didExecuteWithResults:messages: method if you want to be notified when the task finishes execution successfully. The results of the operation, as well as any messages that were generated during geoprocessing, are provided to this method. The results are an array of AGSGPParameterValue objects, and the messages are an array of AGSGPMessage objects.

func geoprocessor(geoprocessor: AGSGeoprocessor!, operation op: NSOperation!, didExecuteWithResults results: [AnyObject]!, messages: [AnyObject]!) {
 for param in results as [AGSGPParameterValue] {
  println("Parameter: \(, Value: \(param.value)")

To be notified of task execution failure, you need to implement the geoprocessor:operation:didFailExecuteWithError: method. The reason for failure is provided to the method.

For asynchronous task execution, you need to implement the geoprocessor:operation:didSubmitJob: method if you want to be notified once the job has been submitted.

To be notified when the job completes successfully, you need to implement the geoprocessor:operation:jobDidSucceed: method. The messages generated during the geoprocessing operation are provided to you, but you must fetch the results separately. Both of these methods receive a unique ID identifying the job you submitted. This ID will be needed later to fetch the results. You fetch the results by invoking queryResultData:paramName: on the geoprocessor for each output parameter of the geoprocessing task. The result will be returned to your class serving as the geoprocessor’s delegate. Your class needs to implement the geoprocessor:operation:didQueryWithResult:forJob: method to receive the result, and the geoprocessor:operation:ofType:didFailWithError:forJob: method to handle any errors encountered while retrieving the results

func geoprocessor(geoprocessor: AGSGeoprocessor!, operation op: NSOperation!, jobDidSucceed jobInfo: AGSGPJobInfo!) {
 geoprocessor.queryResultData(jobInfo.jobId, paramName: "Report_html")
 geoprocessor.queryResultData(jobInfo.jobId, paramName: "parcels_Buffer1_shp")
func geoprocessor(geoprocessor: AGSGeoprocessor!, operation op: NSOperation!, didQueryWithResult result: AGSGPParameterValue!, forJob jobId: String!) {
 println("Parameter: \(, Value: \(result.value)")

func geoprocessor(geoprocessor: AGSGeoprocessor!, operation op: NSOperation!, ofType opType: AGSGPAsyncOperationType, didFailWithError error: NSError!, forJob jobId: String!) {
 println("Error : \(error)")

To be notified when a job fails, you must implement the geoprocessor:operation:jobDidFail: method. The messages generated during geoprocessing are provided to this method, which may provide clues on why the job failed.

func geoprocessor(geoprocessor: AGSGeoprocessor!, operation op: NSOperation!, jobDidFail jobInfo: AGSGPJobInfo!) { 
 for msg in jobInfo.messages as [AGSGPMessage] {

You can also implement the geoprocessor:willCheckJobStatus: and geoprocessor:operation:didCheckJobStatus: methods to display the network activity indicator whenever the geoprocessor polls for status of the submitted job.

func geoprocessor(geoprocessor: AGSGeoprocessor!, willCheckJobStatus jobInfo: AGSGPJobInfo!) {
 UIApplication.sharedApplication().networkActivityIndicatorVisible = true
func geoprocessor(geoprocessor: AGSGeoprocessor!, operation op: NSOperation!, didCheckJobStatus jobInfo: AGSGPJobInfo!) {
 UIApplication.sharedApplication().networkActivityIndicatorVisible = false

Getting results as a layer or an image

Under most circumstances, geoprocessing services return results to clients in the form of values (text, numbers, dates, and so on). The clients then display these results to the user using the platform capabilities available to them. This works well for results that are not complex to display. For example, a iOS applications can easily display results that are dates, numbers, or text. Even results that are features can be displayed using the Graphics layer. But sometimes the results may be complex to visualize, such as a hillshade raster or features using advanced cartography. In such situations, geoprocessing services can be configured to use an associated map service to “draw” the result. Clients then access the result as an image, or as a layer that can be added to the map. In both cases, the heavy lifting is done by ArcGIS Server to transform the result into a format that can be easily displayed on the client.

To get the result as an image, you need to invoke the queryResultImage:paramName:imageParams: method on the geoprocessor. The image will be returned to the geoprocessor delegate’s geoprocessor:operation:didQueryWithResultImage:forJob: method. You can then display this image to users using CocoaTouch UIImageView.

To get the result as a layer, you need to invoke the queryResultImageLayer:paramName: method on the geoprocessor. The layer will be returned as an AGSGPResultLayer object to the geoprocessor delegate through the geoprocessor:operation:didQueryWithResultImageLayer:forJob: method. You can then add this layer to the map to display the results on the map.

See also