After parsing JSON -viewForAnnotation, only one single annotation is displayed on MKMapView

I need to show about 10 locations (and corresponding annotations) on my MkMapView, and after clicking the button I need to add new different annotations according to different JSON analysis results (for example, locationIDValue <100 means red contact, otherwise green). This is simplified code:

- (void)viewDidLoad { [super viewDidLoad]; map.showsUserLocation = true; map.mapType = MKMapTypeStandard; arrayID = [[NSMutableArray alloc] initWithObjects: @"id1", @"id2", @"id3", @"id4", @"id5", @"id6", @"id7", @"id8", @"id9", @"id10", nil]; #define MakeLocation(lat,lon) [[CLLocation alloc] initWithLatitude:lat longitude:lon] locations= @[ MakeLocation(lat1,lon1), MakeLocation(lat2,lon2), MakeLocation(lat3,lon3), MakeLocation(lat4,lon4), MakeLocation(lat5,lon5), MakeLocation(lat6,lon6), MakeLocation(lat7,lon7), MakeLocation(lat8,lon8), MakeLocation(lat9,lon9), MakeLocation(lat10,lon10) ]; for (int l=0; l<[locations count]; l++) { // HERE ITS PERFECT! I CAN SEE ALL 10 ANNOTATIONS! MKPointAnnotation* annotation= [MKPointAnnotation new]; annotation.coordinate = [locations[l] coordinate]; [map addAnnotation: annotation]; } } 

and

  - (IBAction)parseMethod { [map removeAnnotations:map.annotations]; for (int i=0; i < [arrayID count]; i++) { // arrayID contains ID values to parse for each location NSURL *url = [NSURL URLWithString: [NSString stringWithFormat: @"http://JSONPARSINGURL/%@",[arrayID objectAtIndex:i]]]; NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:5.0]; operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { // PARSING CODE . . . NSMutableArray *value = [JSON objectForKey:@"value"]; NSMutableDictionary *value0 = [value objectAtIndex:0]; [valueID replaceObjectAtIndex:i withObject:[value0 objectForKey:@"valueID"]]; locationIDValue = [[valueID objectAtIndex:i] intValue]; // locationIDValue contains the values that i must use to put different annotations on the map NSLog(@"locationIDValue: %d", locationIDValue); // here I control IF app parses all the values of locationIDValue [table reloadData]; // here I put another control to see all values parsed } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { NSLog(@"FAILURE"); }]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // I have used also simple [operation start] but I have same issue! [queue addOperation:operation]; [queue waitUntilAllOperationsAreFinished]; } NSLog(@"END PARSING"); // here I control the end of parsing, so now I can add new annotations to MKMapView according to locationIDValue array MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init]; for (int l=0; l<[locations count]; l++) { // HERE I CAN SEE ONLY A SINGLE LOCATION! annotation.coordinate = [locations[l] coordinate]; NSLog(@"%f - %f", annotation.coordinate.latitude, annotation.coordinate.longitude); // here I control IF app parses all the values of coordinates [map addAnnotation: annotation]; } } 

and

 - (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { MKPinAnnotationView *pinView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pinView"]; pinView.animatesDrop=YES; if (annotation != map.userLocation) { if ( locationIDValue <= 100) { pinView.pinColor = MKPinAnnotationColorRed; return pinView; } pinView.pinColor = MKPinAnnotationColorGreen; return pinView; } else map.userLocation.title = @"My position"; return nil; } 

Situation: When I open the application for the first time, everything is in order, I can see ALL annotations that appear on the map, in accordance with C # define the latitude and longitude of MakeLocation; but if I press the button and run the parseMethod method, I will wait a few seconds (according to NSOperationQueue, but I can check it without waiting, with a simple start code [operation start]), then I can see ONLY ONE ONE explanatory text on the map, always the same thing, strange in FIFTH position, with lat5-lon5 coordinates (otherwise, if I change several codes, I can see ALL ANNOTATIONS that go to ONLY a place). As I can see, I am writing NSLog code and adding a UITableView to control activity, and this is the result:

 END PARSING coordinates: lat1 - lon1 coordinates: lat2 - lon2 coordinates: lat3 - lon3 coordinates: lat4 - lon4 coordinates: lat5 - lon5 <--- THE STRANGE POSITION coordinates: lat6 - lon6 coordinates: lat7 - lon7 coordinates: lat8 - lon8 coordinates: lat9 - lon9 coordinates: lat10 - lon10 locationIDValue: 100 locationIDValue: 90 locationIDValue: 50 locationIDValue: 120 locationIDValue: 20 locationIDValue: 40 locationIDValue: 80 locationIDValue: 180 locationIDValue: 140 locationIDValue: 10 

Well, it seems PERFECT: the application parses all the data (also the UITableView fills the rows with all the new values), so AFTER the parsing operation is completed, I think we have EVERY value needed to fill the map with new annotations. Well, what's wrong here? Why, after parsing, can I see only one annotation? Or are ALL annotations omitted in one place? Please give me some help!

+1
source share
2 answers

In parseMethod change this:

 MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init]; for (int l=0; l<[locations count]; l++) { // HERE I CAN SEE ONLY A SINGLE LOCATION! annotation.coordinate = [locations[l] coordinate]; NSLog(@"%f - %f", annotation.coordinate.latitude, annotation.coordinate.longitude); // here I control IF app parses all the values of coordinates [map addAnnotation: annotation]; } 

:

 for (int l=0; l<[locations count]; l++) { // HERE I CAN SEE ONLY A SINGLE LOCATION! //create a NEW annotation for each location... MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init]; annotation.coordinate = [locations[l] coordinate]; NSLog(@"%f - %f", annotation.coordinate.latitude, annotation.coordinate.longitude); // here I control IF app parses all the values of coordinates [map addAnnotation: annotation]; } 

Move MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init] inside the for loop so that a new annotation object is created for each object.

Existing code creates a single annotation object and simply retains its coordinate.

+3
source

What is also very important to note (because it was very difficult to find this error, and I sat all night before this ...) - check if your object that matches MKAnotation matches the base class of the wizard that implements isEqual and / or hash methods only for base class data, and you do not overwrite it in your base class. That was my problem, and so isqual returned YES for all annotations, and THUS it always showed only one annotation on the map. I could not find any hints about this on the Internet, so I will leave at least this comment for poor people in the same situation.

0
source

Source: https://habr.com/ru/post/1343691/


All Articles