Question

UPDATE: As of iOS 5 and Xcode 4.1 is is now possible to test location in the simulator and even define routes. See http://developer.apple.com for more details.

Legacy Question

Is there anyway to test CoreLocation on the iPhone Simulator?

All I require is to be able to set the location myself and have CoreLocation return it.

Was it helpful?

Solution 2

Thanks for the great feedback, it has prompted me to find a robust solution.

All the code can be found here:

http://code.google.com/p/dlocation/

It is very messy but as I use it it will be become much better.

The solution was to subclass CLLocationManager and define a new delegate @protocol, called DLocationManagerDelegate.

It is designed to be a simple drop-in replacement for CLLocationManagerDelegate that compiles down to a very thin layer when deployed on an actual device.

When running on the device it will return data as normal using CoreLocation, but in the simulator it will read latitude and longitude from a text file (defined in the DLocationManager.h file).

I hope this helps, the implementation is on the simple side and you have to startUpdatingLocation and stopUpdatingLocation to update the display.

Comments and feedback will be gratefully received.

OTHER TIPS

Here is my simple hack that forces the CLLocationMager to return the geocoords of Powell's Tech Bookstore only on the simulator:

#ifdef TARGET_IPHONE_SIMULATOR 

@interface CLLocationManager (Simulator)
@end

@implementation CLLocationManager (Simulator)

-(void)startUpdatingLocation {
    CLLocation *powellsTech = [[[CLLocation alloc] initWithLatitude:45.523450 longitude:-122.678897] autorelease];
    [self.delegate locationManager:self
               didUpdateToLocation:powellsTech
                      fromLocation:powellsTech];    
}

@end

#endif // TARGET_IPHONE_SIMULATOR

Use a filtering function to swap in a test instance when running on the simulator. Wherever you previously received the location (delegate call, etc), pass it through this:

+ (CLLocation *) wakkawakka: (CLLocation*) loc {
#ifdef TARGET_IPHONE_SIMULATOR
    /* replace with a test instance */
    return [[CLLocation alloc] initWithLatitude:10.0 longitude:20.0];
#else
    return loc;
#endif
}

Memory management issues aside...

I think there's another (better IMHO) approach here than subclassing CLLocationManager like in

http://code.google.com/p/dlocation/

In ObjectiveC it seems to be possible to replace an existing method from a class without overriding it. This is often called "method swizzling" : you define your own category for an existing class an implement an existing method in it.

From the client perspective, everything is transparent : he has the feeling he's dealing with the real CLLocationManager but actually, you "took the control from it". So that he doesn't need to deal with any special subclass or any special delegate protocol : he keeps on using the same class / protocol as the one from CoreLocation.

Here's an example to took the control over the delegate a client would inject :

 
@implementation CLLocationManager (simulator) 

-(void) setDelegate:(id)delegate { //your own implementation of the setDelegate... } -(id)delegate { //your own implementation of the delegate.... } -(void)startUpdatingLocation { } -(void)stopUpdatingLocation { } //.... //same for the rest of any method available in the standard CLLocationManager @end

Then in this implementation, you're free to deal with a pre defined set of coordinates (coming from a file of whatever) that will be "pushed" to the delegate using the standard CLLocationManagerDelegate protocol.

Trigger the Core Location callbacks from a test class, if you need to set a location other than the one the simulator gives you.

the locationManager:didUpdateToLocation and locationManager:didFailedWithError overloaded callbacks are never called in the iphone simulator, that's kinda strange, all i get is 0.0000 for lat., and 0.0000 for lon. as the position. In the situation you develop something, that's kinda hard to implement all the possible situations that can occur during the location handling, using only simulator environment.

If you're interested in updating the blue userLocation dot in a MKMapView with the simulated location updates, check out my FTLocationSimulator at http://github.com/futuretap/FTLocationSimulator

It reads a KML file generated by Google Earth to provide continuous location updates.

Testing CoreLocation on iPhone Simulator

1) To test the location in simulator,best way is to use GPX files,just go to Files -> New -> Resource -> GPX File.

2) After Adding the GPX file update the location coordinates as desired.

3) once the GPX file is added to the project,Select the Scheme -> Edit Scheme -> Run -> Allow Location Simulation.tick the location simulation and select the name of the GPX file you just created.

this way simulator will always pick your desired coordinates,that we have added in our GPX File.

Create the GPX file

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top