I have a custom class called Device which implements the MKAnnotation protocol. In the examples I’m following (MapKit and Core Location on the iPad from O’Reilly Media), they say to check if the annotation I want to add is an MKUserLocation class and return nil if it is. I fully understand what that does, but the problem is that my Device class is always identified as MKUserLocation so it always returns nil so I never get any annotations added to the map. I’ve gone over the code again and again and again. I’ve the O’Reilly code samples as well and I can’t see where I’m going off. It’s really frustrating.
Here’s my Device.m:
@implementation Device
@synthesize udId, user, latitude, longitude;
- (CLLocationCoordinate2D)coordinate {
CLLocationCoordinate2D internalCoordinate;
internalCoordinate.latitude = [self.latitude doubleValue];
internalCoordinate.longitude = [self.longitude doubleValue];
return internalCoordinate;
}
- (NSString *)title {
return self.user;
}
- (NSString *)subtitle {
return nil;
}
- (id)initWithUDId:(NSString *)_udId User:(NSString *)_user Latitude:(NSNumber *)_latitude Longitude:(NSNumber *)_longitude {
if (self == [super init]) {
self.udId = _udId;
self.user = _user;
self.latitude = _latitude;
self.longitude = _longitude;
}
return self;
}
- (void)dealloc {
[udId release];
self.udId = nil;
[user release];
self.user = nil;
[latitude release];
self.latitude = nil;
[longitude release];
self.longitude = nil;
[super dealloc];
}
@end
And here’s my DeviceMapAnnotator.m:
@implementation DeviceMapAnnotator
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
NSLog(@"annotation is an MKUserLocation class");
return nil;
}
MKPinAnnotationView *deviceAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"DeviceAnnotation"];
if (deviceAnnotationView == nil) {
deviceAnnotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"DeviceAnnotation"] autorelease];
deviceAnnotationView.animatesDrop = NO;
deviceAnnotationView.pinColor = MKPinAnnotationColorRed;
}
return deviceAnnotationView;
}
- (void)dealloc {
[super dealloc];
}
@end
And here’s the code calling it from my DashboardViewController.m:
- (void)updateMapAnnotations:(NSArray *)devices {
for (Device *device in devices) {
[map addAnnotation:device];
}
}
And here’s the code calling updateMapAnnotations from my app delegate:
- (void)requestFinished:(ASIHTTPRequest *)request {
if (![request error]) {
NSError *jsonError = nil;
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithJSONString:[request responseString] error:&jsonError];
if (!jsonError || ([[jsonDictionary objectForKey:@"Success"] intValue] == 1)) {
NSArray *jsonDevicesArray = [jsonDictionary objectForKey:@"Devices"];
NSMutableArray *devicesArray = [[NSMutableArray alloc] initWithCapacity:[jsonDevicesArray count]];
for (NSDictionary *deviceDictionary in jsonDevicesArray) {
[devicesArray addObject:[[[Device alloc] initWithUDId:[deviceDictionary objectForKey:@"UDId"] User:[deviceDictionary objectForKey:@"User"] Latitude:[NSNumber numberWithDouble:[[deviceDictionary objectForKey:@"Latitude"] doubleValue]] Longitude:[NSNumber numberWithDouble:[[deviceDictionary objectForKey:@"Longitude"] doubleValue]]] autorelease]];
}
[dashboardViewController updateMapAnnotations:devicesArray];
} else {
// AUTHORIZATION FAILED
}
}
}
I basically make a call to the server every 45 seconds, get a list of devices and their locations as a JSON string which is then deserialized into an NSArray containing Device objects. I then pass the array to updateMapAnnotations which then loops it and calls addAnnotation. The whole process works, and I guarantee that the objects being sent to DeviceMapAnnotator are of type Device, however the MKUserLocation check always returns prematurely and the whole process is just stopped dead in the water.
I would really appreciate it if someone who knows what they’re doing with iOS/Objective-C, etc, can help me out (that’s pretty much everyone because I apparently am an idiot).
Just to vent, I must say that Objective-C is getting on my $hit list really fast.
Okay, I got it to work, although I don’t know exactly what the solution was. In the end I scrapped everything and rewrote it from scratch in a new file and it worked at that point. I also realized that I was not sending back the latitude and logitude in the JSON, however that still wasn’t the problem because they would be initialized as 0.0 anyway. In the end I have no idea what really fixed it, but it works, so I’ll take it.
Sorry to waste your guys’ time. 🙁