0

I have a function which prepares data for my UITableView:

- (void) SearchFromMyPosition {

   TitleLabelSort    = [[NSMutableArray alloc] init];
   DistanceLabelSort = [[NSMutableArray alloc] init];
   TagValueSort      = [[NSMutableArray alloc] init];
   DistanceUnitSort  = [[NSMutableArray alloc] init];
   LatArraySort      = [[NSMutableArray alloc] init];
   LngArraySort      = [[NSMutableArray alloc] init];

   // loading
  [activityIndicatorObject startAnimating];

  NSNumber *latNr1 = [[NSUserDefaults standardUserDefaults] valueForKey:@"api_lat"];
  NSNumber *lngNr1 = [[NSUserDefaults standardUserDefaults] valueForKey:@"api_lng"];
  double lat1 = [latNr1 doubleValue];
  double lng1 = [lngNr1 doubleValue];

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSArray *array = [APIConnection GetDataFromUrlAuth];

    dispatch_async(dispatch_get_main_queue(), ^{

        for (NSString *item in array) {

            NSArray *coords = [[[array valueForKey:item] valueForKey:@"location"] componentsSeparatedByString:@"|"];

            double lat2 = [[coords objectAtIndex:0] doubleValue];
            double lng2 = [[coords objectAtIndex:1] doubleValue];

            CLLocation *oldLocation = [[CLLocation alloc] initWithLatitude:lat1 longitude:lng1];
            CLLocation *newLocation = [[CLLocation alloc] initWithLatitude:lat2 longitude:lng2];
            CLLocationDistance meters = [newLocation distanceFromLocation:oldLocation];

            [LatArraySort addObject:[NSString stringWithFormat:@"%f",lat2]];
            [LngArraySort addObject:[NSString stringWithFormat:@"%f",lng2]];
            [TitleLabelSort addObject:[[array valueForKey:item] valueForKey:@"name"]];
            [DistanceLabelSort addObject:[NSString stringWithFormat:@"%f",meters]];
            [TagValueSort addObject:item];

            [self.myTableView reloadData];
            [activityIndicatorObject stopAnimating];
        }

    });
  });
}

This works but I need to sort results by DistanceLabelSort For sorting CoreData results I use below function and works fine:

- (void) SetTableData {

   TitleLabel    = [[NSMutableArray alloc] init];
   DistanceLabel = [[NSMutableArray alloc] init];
   TagValue      = [[NSMutableArray alloc] init];
   DistanceUnit  = [[NSMutableArray alloc] init];
   LatArray      = [[NSMutableArray alloc] init];
   LngArray      = [[NSMutableArray alloc] init];

   // sorting
   NSArray *sortedArray = [DistanceLabelSort sortedArrayUsingComparator:^(NSString *str1, NSString *str2) {
    return [str1 compare:str2 options:NSNumericSearch];
}];

   NSString *sortIdentStr = [[NSString alloc] init];
   unsigned long sortIdent;

   NSMutableArray *arrayUnit = [[NSMutableArray alloc] init];

   for (int i = 0; i < sortedArray.count; i++) {

    sortIdentStr = [sortedArray objectAtIndex:i];
    sortIdent    = [DistanceLabel indexOfObject:sortIdentStr];

    arrayUnit = [self unitStr:sortIdentStr];

    [TitleLabel addObject:[TitleLabelSort objectAtIndex:sortIdent]];
    [TagValue addObject:[TagValueSort objectAtIndex:sortIdent]];
    [LatArray addObject:[LatArraySort objectAtIndex:sortIdent]];
    [LngArray addObject:[LngArraySort objectAtIndex:sortIdent]];

    [DistanceLabel addObject:[arrayUnit objectAtIndex:0]];
    [DistanceUnit addObject:[arrayUnit objectAtIndex:1]];

    [self.myTableView reloadData];
    [activityIndicatorObject stopAnimating];
   }
}

But if I try use this for sorting data from external api function SetTableData is done before I get results from external api.

Volker
  • 4,640
  • 1
  • 23
  • 31
Nizzre
  • 275
  • 1
  • 6
  • 14
  • http://stackoverflow.com/questions/14541458/how-to-sort-an-array-of-dates-in-descending-order – Kirit Modi Apr 01 '14 at 06:23
  • I think that problem is not in sorting but in tasks priority. I tried to use solution from http://stackoverflow.com/questions/11909629/waiting-until-two-async-blocks-are-executed-before-starting-another-block but function SetTableData was done befor a block. The block should be done first. – Nizzre Apr 01 '14 at 08:11

1 Answers1

0

Finally I found solution and maybe this will be helpful for others:

I added function which checks if the task is done:

- (void)SearchFromMyPositionWithSuccess:(void (^)(void))successHandler failure:(void (^)(void))failureHandler {

  TitleLabelSort    = [[NSMutableArray alloc] init];
  DistanceLabelSort = [[NSMutableArray alloc] init];
  TagValueSort      = [[NSMutableArray alloc] init];
  DistanceUnitSort  = [[NSMutableArray alloc] init];
  LatArraySort      = [[NSMutableArray alloc] init];
  LngArraySort      = [[NSMutableArray alloc] init];

  // loading
 [activityIndicatorObject startAnimating];

 NSNumber *latNr1 = [[NSUserDefaults standardUserDefaults] valueForKey:@"api_lat"];
 NSNumber *lngNr1 = [[NSUserDefaults standardUserDefaults] valueForKey:@"api_lng"];
 double lat1 = [latNr1 doubleValue];
 double lng1 = [lngNr1 doubleValue];

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

   NSArray *array = [APIConnection GetDataFromUrlAuth];

   dispatch_async(dispatch_get_main_queue(), ^{

    int i = 0;
    for (NSString *item in array) {
        i++;
        NSArray *coords = [[[array valueForKey:item] valueForKey:@"location"] componentsSeparatedByString:@"|"];

        double lat2 = [[coords objectAtIndex:0] doubleValue];
        double lng2 = [[coords objectAtIndex:1] doubleValue];

        CLLocation *oldLocation = [[CLLocation alloc] initWithLatitude:lat1 longitude:lng1];
        CLLocation *newLocation = [[CLLocation alloc] initWithLatitude:lat2 longitude:lng2];
        CLLocationDistance meters = [newLocation distanceFromLocation:oldLocation];

        [LatArraySort addObject:[NSString stringWithFormat:@"%f",lat2]];
        [LngArraySort addObject:[NSString stringWithFormat:@"%f",lng2]];
        [TitleLabelSort addObject:[[array valueForKey:item] valueForKey:@"name"]];
        [DistanceLabelSort addObject:[NSString stringWithFormat:@"%f",meters]];
        [TagValueSort addObject:item];

        if (i == array.count) {
            successHandler();
        }           

        [activityIndicatorObject stopAnimating];
    }

   });
 });
}

And wait for success in this function:

-(void) SearchFromMyPosition {
   [self SearchFromMyPositionWithSuccess: ^{

       [self SetTableData];

       NSLog(@"success");
   } failure:^{
       NSLog(@"failure");
   }];
}

This solves my case :)

Nizzre
  • 275
  • 1
  • 6
  • 14