A small Flask app with a Leaflet map front-end that injects a simulated GPS location onto a USB-connected iPhone and walks it along real streets at a set pace. Click a point to teleport, draw a multi-point circuit, or replay a GPX track; live position streams back to the map over SSE. Built to experiment with location-based apps on hardware I own — and mostly an excuse to reverse how iOS 17+ developer tunneling and CoreLocation source-tagging actually work.
Great-circle math (haversine / bearing / step-along-bearing) moves the position between waypoints. The engine ticks twice a second so iOS sees a steady stream of fixes and derives speed and course from the cadence. A clean navigation path is tracked separately from the jittered position that's actually reported, so the underlying route stays exact while the reported fix wobbles like a real receiver.
tunneld
process to bring up the network interface. Getting a stable DVT/instruments session over that tunnel
was the bulk of the work.Settings → Privacy & Security → Developer Mode simply does not exist until a
developer tool pokes the device the right way — pymobiledevice3 amfi reveal-developer-mode
is what makes the switch appear. A plain USB/lockdown connection isn't enough on current iOS.pymobiledevice3 releases, so I bridged the
async device calls onto a background event loop to keep the engine's tick loop synchronous.CLLocationSourceInformation.isSimulatedBySoftware = true. The flag comes from the
OS, not the coordinates — a clean, honest signal any app can read. The only ways to produce an
unflagged fix are RF-level GNSS spoofing (transmitting L1 — regulated spectrum) or OS-level
hooks. Good reminder that the robust anti-spoof check is the source flag plus a motion-sensor
cross-check, not coordinate realism.