Is there any alternative way to run multiple queries to different layers together? (iOS)

09-22-2015 07:36 PM
New Contributor II

In my case, I need to query from 3 map layers and get non-graphic information data and display them in 3 table lists.

I tried to use NSOperationQueue to manage

- (NSOperation *)executeWithQuery:(AGSQuery *)query;

But this returned NSOperation is already running, thus cannot be added to NSOperationQueue.

Below is how I roughly achieved but I really think it's a bad practice, because for this case I created 3 booleans and 3 AGSQueryTasks for 3 queries, and more variables will be needed if need to query from more layers.

I hope you guys can have a better way to introduce.

@interface MultipleQueryTest () <AGSQueryTaskDelegate>
    BOOL _multipleQueryStart;
    BOOL _flagQueryOperationAComplete;
    BOOL _flagQueryOperationBComplete;
    BOOL _flagQueryOperationCComplete;

    AGSQueryTask *_queryTaskA;
    AGSQueryTask *_queryTaskB;
    AGSQueryTask *_queryTaskC;
    NSArray *_resultA;
    NSArray *_resultB;
    NSArray *_resultC;

@implementation MultipleQueryTest

- (IBAction)btnGoTapped:(id)sender
    _multipleQueryStart = YES;

    // query A
    NSURL *layerAURL = [self getURLForLayer: eLayerA];
    NSArray *outFieldsA = [NSArray arrayWithObjects:@"field1", @"field2", ... nil];
    NSOperation *queryOpA = [self startQuyerOperationWithURL:layerAURL outFields:outFieldsA operationType:eOperationTypeA]; = @"operationA";
    _flagQueryOperationACompleted = NO;

     // query B
   NSURL *layerBURL = [self getURLForLayer: eLayerB];
   NSArray *outFieldsB = [NSArray arrayWithObjects:@"field1", @"field2", ... nil];
   NSOperation *queryOpB = [self startQuyerOperationWithURL:layerBURL outFields:outFieldsB operationType:eOperationTypeB]; = @"operationB";
   _flagQueryOperationBCompleted = NO;

   // query C
   NSURL *layerCURL = [self getURLForLayer: eLayerC];
   NSArray *outFieldsC = [NSArray arrayWithObjects:@"field1", @"field2", ... nil];
   NSOperation *queryOpC = [self startQuyerOperationWithURL:layerCURL outFields:outFieldsC operationType:eOperationTypeC]; = @"operationC";
   _flagQueryOperationCCompleted = NO;

- (NSOperation *)startQuyerOperationWithURL:(NSURL *)layerURL outFields:(NSArray *)outFields operationType:(eOperationType)opType
   AGSQuery *query = [AGSQuery query];
   query.outSpatialReference = self.mapView.spatialReference;
   query.outFields = outFields;
   query.returnGeometry = NO;
   AGSQueryTask queryTaskObj = [[AGSQueryTask alloc] initWithURL: layerURL];
   queryTaskObj.delegate = self;

   if (opType == eOperationTypeA)
      _queryTaskA = queryTaskObj;
      return [_queryTaskA executeWithQuery:query];
   else if (opType == eOperationTypeB)
      _queryTaskB = queryTaskObj;
      return [_queryTaskB executeWithQuery:query];
   else if (opType == eOperationTypeC)
      _queryTaskC = queryTaskObj;
      return [_queryTaskC executeWithQuery:query];
      return nil;

#pragma mark - AGSQueryTaskDelegate

- (void)queryTask:(AGSQueryTask *)queryTask operation:(NSOperation *)op didExecuteWithFeatureSetResult:(AGSFeatureSet *)featureSet
    if (_multipleQueryStart)
      if ([ isEqualToString:@"operationA"]) {
         _resultA = featureSet.features;
         _flagQueryOperationACompleted = YES;
         _queryTaskA = nil;
      else if ([ isEqualToString:@"operationB"]) {
         _resultB = featureSet.features;
         _flagQueryOperationBCompleted = YES;
         _queryTaskB = nil;
      else if ([ isEqualToString:@"operationC"]) {
         _resultC = featureSet.features;
         _flagQueryOperationCCompleted = YES;
         _queryTaskC = nil;
      if (_flagQueryOperationACompleted && _flagQueryOperationBCompleted && _flagQueryOperationCCompleted)
         NSLog(@"All list received.......");
         _multipleQueryStart = NO;
0 Kudos
1 Reply
New Contributor

Not sure if its too late for the reply, you create separate class with nsobject and agsquerytaskdelegate  and for each query task reference in your view controller assign the delegate to another class.

That way you will have 3 class with agsquerytaskdelegate and from view controller you are assigning delegates to each on them.

Let me know if you need sample of codes.

Varun Chudiwale

0 Kudos