Whereami under iOS 4.2.1


#1

Under iOS 4.2.1, the mapView:didAddAnnotationViews: method is not being called when the user’s location is updated. I saw another post in this forum that mentioned that with iOS 4.2, Apple may have changed the method to mapView:didUpdateUserLocation:. This new method does not take the same parameters, but this is good as the resulting code to zoom the MapView to the user’s current location is a bit simpler:

- (void)mapView:(MKMapView *)mv didUpdateUserLocation:(MKUserLocation *)userLocation { MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([userLocation coordinate], 250, 250); [mv setRegion:region animated:YES]; }

Since MKUserLocation conforms to the MKAnnotation protocol, and since the coordinate property is required, you can safely ask the userLocation object for its coordinate.

This being my first post here, please by all means let me know if I’m doing anything wrong here.


#2

According to Apple’s documentation for didUpdateUserLocation, as of iOS 4.0, the following is true:

“While the showsUserLocation property is set to YES, this method is called whenever a new location update is received by the map view.”

So, didAddAnnotationViews doesn’t get called until you add an annotation. I found this out via NSLog (it’s your friend). I added Paul’s method to my code, but I also left in the method from the book. Later on, when you add text and actually create a MapPoint, the method from the book gets called (makes sense, since we’re adding annotation - red pin versus blue pin). Technically, the code that exists in this method really doesn’t matter anymore, since it does the same thing as what Paul outlined. Still, interesting nonetheless, at least to me.


#3

Hey All, I’d like to bump this thread with a related problem. When I run my app in the simulator with iOS 4.3, it:

  1. Puts a blue dot at Cupertino & zooms in to a 250x250 range. At this point, I log the fact that the “didAddAnnotationViews” method is called (which handles the zooming).
  2. When I type something & hit Enter, it adds a red annotation to my current location, but doesn’t actually zoom to that location. I also log from the “didUpdateToLocation” method, which is fired correctly with my (not Cupertino) location. Within that method, I call addAnnotation, which successfully adds an annotation at my current location. However, the didAddAnnotationViews implementation does not fire.

So, I’m thoroughly confused. I thought the “didAddAnnotationViews” method is called whenever you call [mapView addAnnotation: annotation], which seems to be working (there are annotations when I find my location on the map). Furthermore, I implemented another method in the MKMapViewDelegate protocol (mapViewDidFinishLoadingMap) just to ensure my delegate was wired in correctly, and it worked. So for some reason didAddAnnotationViews is not firing as I expect. Here’s my code, any help is greatly appreciated.

Thanks

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
    NSLog(@"Entering didAddAnnotationViews");
    MKAnnotationView *annotationView = [views objectAtIndex:0];
    id <MKAnnotation> mp = [annotationView annotation];
    MKCoordinateRegion region = 
        MKCoordinateRegionMakeWithDistance([mp coordinate], 250, 250);
    [mapView setRegion:region animated:YES];
}

- (void)locationManager:(CLLocationManager *)manager 
	didUpdateToLocation:(CLLocation *)newLocation 
		   fromLocation:(CLLocation *)oldLocation
{
    // How many seconds ago was this new location created?
    NSTimeInterval t = [[newLocation timestamp] timeIntervalSinceNow];
    if (t < -180) {
        return;
    }
    MapPoint *mp = [[MapPoint alloc] 
                    initWithCoordinate:[newLocation coordinate] 
                    title:[textField text]];
    NSLog(@"Calling add annotation");
    [worldView addAnnotation:mp];
    [mp release];
    [self foundLocation];
}

And here’s the log output. Note that when we start, we do enter “didAddAnnotationViews”, but after actually adding an annotation, we don’t.

2011-05-16 08:48:08.975 Whereami[4406:207] Entering didAddAnnotationViews
2011-05-16 08:51:56.420 Whereami[4406:207] entering textFieldShouldReturn
2011-05-16 08:51:56.420 Whereami[4406:207] entering find location
2011-05-16 08:51:57.278 Whereami[4406:207] Calling add annotation
2011-05-16 08:51:57.279 Whereami[4406:207] entering found location

#4

I’d like to bump this thread again.

I’m using the newer implementation outlined in the 2nd edition book (using didUpdateUserLocation). I’m using xCode 4.0.2 and 4.3 iOS simulator. I am getting only the Cupertino location showing up. I can successfully zoom into that location, but I never get my current location. From the earlier chapter, using CLLocationManagerDelegate protocol and didUpdateToLocation, I got a location about 20 miles from my current location (much closer than Cupertino is to me). My questions are:

using CLLocationManager and the simulator, where is the location information coming from (I have an Ethernet and AirPort connections)?
Why does CLLocationManager give a location different than MapKit (MapKit provides only Cupertino)?

I read a tutorial raywenderlich.com/2847/intro … s-tutorial
which says that MapKit will always use Cupertino as the location when using the simulator. Is this true?

I’m confused.


#5

I’m new to this so don’t know a lot about how MapKit works, but for updates, the documentation states network location can be used as the user location which could account for a location that is close but does match your exact position when using a wireless connection instead of the GPS capability.

Another known problem I’m trying to address is the GPS bug in 4.1 simulator where update user location does not work with the iOS simulator. Makes checking the app difficult since it hangs trying to update the location.

Fred


#6

My question related to different CLLocationManagers being used MapView vs Annotation. MapView uses its own location manager whereas annotation uses the CLLocationManager expilcitly instantiated in whereami. Deriving location seems to be based on many factors (cellular triangulation, WiFi crowd sourcing, IP address, GPS). It is somewhat non-deterministic. Therefore, I was seeing entirely different locations (off by hundreds of miles) on the MapView vs the MapPoint annotation. Once I provisioned an iPad and ran it on real hardware, the issue went away. I guess there are bugs in the simulator location services.