Domanda

I am trying to show information on a map from a json but nothing happens I think there is something missing so the information can be shown on the map Manage to get the json working and get information on the log, now I would like to know who to create the nsdictionary and the array so that I can show then the information on the mapview. Here is war I have so far with the array:

NSData *data =[NSData dataWithContentsOfURL:[NSURL URLWithString:@"URL"]];

NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

NSLog(@"Datos Obtenidos:\n%@",dict);
NSDictionary *cortes;
NSError* error;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data
                                                     options:kNilOptions
                                                       error:&error];
NSMutableArray *jsonCheckins = [NSMutableArray array];
for(NSDictionary *jsonElement in jsonArray){
    InitViewController *checkin = [InitViewController checkinFromDictionary:jsonElement];
    [jsonCheckins addObject:checkin];
}

Manage to add this code but still the information is not showning on the mapview:

- (CLLocationCoordinate2D) checkinCoordinate { 
   CLLocationCoordinate2D coordinate;
   coordinate.latitude = self.checkin.latitud;
   coordinate.longitude = self.checkin.longitud;
   return coordinate;}

- (void)showCheckinAnnotation { 
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
annotationPoint.coordinate = [self checkinCoordinate];
annotationPoint.title = self.checkin.type;
annotationPoint.subtitle = self.checkin.description;
[self.mapView addAnnotation:annotationPoint];}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKAnnotationView *annotationView= nil;
if(annotation != mapView.userLocation) {
static NSString *annotationViewId = @"annotationViewId";
annotationView = (MKAnnotationView *)[mapView         
dequeueReusableAnnotationViewWithIdentifier:annotationViewId];
if (annotationView == nil) {
    annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationViewId];
       }
   }
 return annotationView;}
È stato utile?

Soluzione

We don't see your checkinFromDictionary, so it's hard for us to comment because we never see you set this self.checkin property, but it's worrying. But we'd need to see more code to comment further on that.

But, just to demonstrate, here's a method that looks up and adds all the annotations without incident:

NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.buenosairescortes.com.ar/capitalfederalcortes/getCortes.php"]];

NSError *error;
NSArray *array = [NSJSONSerialization JSONObjectWithData:data
                                                options:0
                                                  error:&error];

if (error)
{
    NSLog(@"%s: error=%@", __FUNCTION__, error);
    return;
}

for (NSDictionary *dictionary in array)
{
    MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
    annotation.coordinate = CLLocationCoordinate2DMake([dictionary[@"latitude"] doubleValue],
                                                       [dictionary[@"longitude"] doubleValue]);
    annotation.title = dictionary[@"type"];
    annotation.subtitle = dictionary[@"description"];
    [self.mapView addAnnotation:annotation];
}

(By the way, I use the CLLocationCoordinate2dMake method, which is part of the CoreLocation.framework, but you can probably use your method, too.)

In terms of your viewForAnnotation, it seems unnecessary as you don't appear to be doing anything that it wouldn't do by default. But let's assume for a second that you wanted it (because maybe you're planning on further customization of the method).

There are two problems with your provided routine:

  • You are creating a MKAnnotationView which doesn't do anything unless you set its image (or subclass it in a class that sets its image). If you just want a standard pin, use MKPinAnnotationView instead.

  • A more subtle problem is that if an annotation view is successfully dequeued, you're not resetting its annotation. So, I'd suggest to include an else clause to that if (annotation == nil) statement.

Thus, that yields:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    MKAnnotationView *annotationView= nil;
    if (![annotation isKindOfClass:[MKUserLocation class]])
    {
        static NSString *annotationViewId = @"annotationViewId";
        annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationViewId];
        if (annotationView == nil)
        {
            annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationViewId];
        }
        else
        {
            annotationView.annotation = annotation;
        }
    }
    return annotationView;
}

This method also checks for whether the annotation class is not a member via

if (![annotation isKindOfClass:[MKUserLocation class]])
{
    // do annotation stuff here
}

instead of

if (annotation != mapView.userLocation)
{
    // do annotation stuff here
}

This is the method that Apple describes in their Location Awareness Programming Guide, so it's probably safer. In general, it's not altogether reliable to check for equality between two objects (perhaps you were lucky here, but it's not generally prudent). Objects that support comparison operations generally have equality methods prefixed with isEqual. Having said that, checking class membership is sufficient here.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top