All guides PinDrift

How to test your app in another location

The Simulator will not catch the bugs that matter. Here is what does, and what each approach is actually good for.

Every app that touches Core Location eventually has a bug that only appears somewhere the developer is not. Here is what the available tooling actually covers.

The short version: the Simulator tests your layout, a GPX file tests your handling of movement, and only a physical device tests the thing that is going to break. If you can do one of the three, do the device. The other two are faster, a reasonable trade as long as you know what you are trading away.

The Simulator

Features, then Location. Presets for a fixed point, a city run, a freeway drive, or a custom coordinate.

Good for: layout with a location present, the permission prompt flow, basic formatting of coordinates and distances.

Bad for: essentially everything about how location behaves in reality. Accuracy is perfect, updates are regular, nothing is suspended, the battery is infinite. Every one of those is false on a phone.

There is a command-line version worth wiring into a script: xcrun simctl location, pointed at a booted device, with a coordinate. The neighbouring command is more useful. xcrun simctl privacy, with the reset action and your bundle identifier, puts an app back to a never-asked state, so you can run the first-launch permission flow twenty times in a morning instead of deleting and reinstalling between each go. Both have changed between Xcode releases, so read the usage text for your version.

GPX playback

A GPX file is a list of waypoints. Add one to your scheme and Xcode plays it back so the location moves.

This is how you test anything involving movement: distance accumulation, heading, speed, route snapping, and whether your UI copes with a position that changes while the user is reading it.

Worth knowing: Xcode interpolates between waypoints at a fixed rate, so the resulting speed is a function of how far apart you spaced them. If you need a realistic speed profile you have to author the spacing deliberately.

Waypoints do not need timestamps, and in the Xcode versions I have used the timestamps are ignored when they are present, so the pacing comes from spacing whatever the file claims. I have not tested that on every release. If a test depends on an exact speed, log the interval between fixes rather than believing the GPX.

An authored route is also smoother than any route a person produces. Real walking wanders, stops, doubles back, and loses the fix under a bridge. Distance logic that over-counts will over-count on the real walk and behave perfectly on the clean line.

A real device

Xcode can push a simulated location to a connected phone, and this is where the useful failures show up.

On iOS 16 and later the phone runs nothing from Xcode until Developer Mode is on, which is a Settings toggle and a reboot. Developer Mode is covered separately. The thing to know before you start is that a location set from Xcode lives inside the debug session. Detach and the phone goes back to reporting where it really is, so anything measured over hours, an overnight background run or a battery figure across a working day, cannot be done this way.

Speed and course are the trap

A location object carries speed and course as well as a coordinate, and both of them can be invalid. iOS signals that with a negative value, and code that plots a fix without checking will draw a garbage point at full confidence. The same goes for horizontal accuracy: negative means the coordinate itself is not to be trusted.

Simulated fixes are exactly where those invalid values turn up. We have tested the developer simulation pathway on real hardware, and what arrives is position only: speed comes back as -1 or 0, never a real figure. We have not checked whether Xcode's GPX playback synthesises a speed from waypoint spacing, so if your feature reads that field, log it on the first run instead of assuming either way.

Course fails from the other end. A stationary fix has no meaningful heading, so an arrow rotated to the course value swings north the moment the user stops walking, and a GPX route never stops.

Region monitoring, specifically

If your app uses geofences, device testing is not optional. The Simulator does not reproduce the confirmation delay before a crossing fires, the 20-region limit per app, or the wake-from-suspended path. All three produce bugs that are invisible until they are in front of a user.

Regions also outlive your process: iOS relaunches the app in the background to deliver a crossing, so the handler has to work from a cold start with no view controller anywhere. And the radius you ask for is not the radius you get, with Apple's guidance putting the practical floor at a couple of hundred metres. A fifty metre geofence does not fail loudly. It fires late, or near the boundary, or once. Geofencing has its own guide.

What a simulated location does not change

Setting a location moves one number. It does not move the rest of the phone, and if the behaviour you are testing depends on any of these, a coordinate tests nothing.

Approximate accuracy is a state, not an edge case

Since iOS 14 there is a second axis on top of when-in-use and always: precise or approximate. Approximate gets skipped in testing and picked by users, because the prompt makes it easy. The fix arrives measured in kilometres rather than metres and refreshed far less often, so a "0.2 miles away" label rendered from one is not slightly wrong, it is fiction. You can request temporary full accuracy, the user can decline, and the decline path is reliably the one nobody writes. The permission states are covered here.

Build a regression set

Pick a handful of coordinates that have historically broken things and keep them: the prime meridian and the equator for sign errors, either side of the antimeridian for wraparound, a high latitude for projection assumptions, and somewhere your app has no data for.

Specifics worth stealing: zero and zero, which sits in the Gulf of Guinea and is also what a failed parse produces, so it catches a second bug for free. A pair either side of 180 degrees longitude, because the naive midpoint lands on the wrong side of the planet. And a place on a half-hour UTC offset, India or Nepal, which breaks arithmetic written by anyone who assumed offsets come in whole hours.

One caution: the system geocoder is rate limited, so a suite that reverse-geocodes forty coordinates in a loop starts failing for reasons unrelated to your change, while looking exactly like it.

Where an external tool fits, and where it does not

Given where you are reading this: if you are building the app, Xcode is the correct tool and you already have it. Nothing we make is a better way to test your own code, and most people who land here should stop at the GPX file. An external spoofer only earns its place where Xcode cannot reach, which is holding a location for hours with no debugger attached, or exercising an app you have no scheme for. The mechanism is written up separately.

The gap in all of it: simulated locations arrive clean. Real ones arrive with poor accuracy, gaps and jumps. Testing that path means injecting values in a debug build, or going outside with the phone, and the second one keeps finding things the first misses.

Frequently asked questions

How do I simulate a location in Xcode?

With the Simulator running, use Features then Location, and pick a preset or enter a custom coordinate. For a moving route, add a GPX file to your scheme and select it as the default location.

Can I test location on a real iPhone?

Yes. Xcode can set a simulated location on a connected device, and it is the only way to test against real GPS accuracy behaviour, real battery cost and real background suspension.

Why does my geofence work in the Simulator but not on a device?

Because the Simulator does not reproduce the confirmation delay, the 20-region limit, or the way iOS suspends and wakes apps. Region monitoring is one of the clearest cases where Simulator results do not transfer.

What is a GPX file used for in testing?

It supplies a sequence of waypoints so the simulated location moves rather than sitting still, which is how you test anything that depends on movement, heading or speed.

How do I test what my app does with a poor GPS fix?

This is the gap in the tooling. Simulated locations arrive with clean accuracy values, and real-world fixes do not. Testing that path usually means either injecting values in a debug build or going outside.

Ellis writes the guides here. Mostly that means reading Apple’s developer documentation so you do not have to, and testing what the tracking apps actually do rather than what their marketing says they do.

Try PinDrift

A real free trial: no card, no account. $9 a month, $60 a year, or $70 once.

Download PinDrift $9/mo, $60/yr, or $70 once