The project's README from github.com/SegFault42/iOS-GPS-Spoofer. As one markdown file: README.md.
Spoof the GPS location of a connected iPhone (iOS 17+) for as long as the tool runs. The fake location is cleared automatically on exit, and re-applied automatically if the device disconnects and reconnects.
Ships as two front-ends over a shared core (SpooferCore):
iosgpsspoofer-gui — a SwiftUI macOS app: auto-detected device list with a
refresh button, a map you click to drop the location, coordinate fields,
presets, transport picker, live log, and a Start/Stop toggle.iosgpsspoof — the CLI (spoof, route, list, clear).It drives Apple's developer location-simulation service — the same mechanism
Xcode's Product ▸ Scheme ▸ Simulate Location uses. On iOS 17+ that service
lives behind the encrypted CoreDevice tunnel, so the actual transport is handled
by pymobiledevice3; this tool is
the user-facing wrapper (CLI, device selection, the "keep it spoofed while
connected" supervision loop, clean teardown).
No build required — grab the DMG from the Releases page:
Open the DMG, drag iOS GPS Spoofer to Applications. First launch: right-click ▸ Open (the app is ad-hoc signed, so Gatekeeper asks once). Then prepare your iPhone — see IPHONE-SETUP.md.
Want to build it yourself instead? See Setup / Package as a DMG.
Click a spot on the map (or type coordinates / pick a preset) and the connected iPhone reports that exact location for as long as the tool runs.

The spoofed position as the iPhone itself sees it — Apple Park, the mid-Atlantic, and the Eiffel Tower:
| Apple Park | North Atlantic | Eiffel Tower |
|---|---|---|
Drop waypoints A → B and any points in between, set a duration (h : m : s) or a speed (km/h), and the iPhone moves along the path at constant speed. Optionally loops.

pymobiledevice3 venv)--transport native, no root is required — it piggybacks
Apple's own remotepairingd tunnel../setup.sh # creates .venv with pymobiledevice3, builds release binary
The binary lands at .build/release/iosgpsspoof. Copy it onto your PATH if you
like (cp .build/release/iosgpsspoof /usr/local/bin/). It looks for
pymobiledevice3 in ./.venv/bin, then next to the binary, then on $PATH; use
--python-path to point at a specific one.
./run-gui.sh # or: .build/release/iosgpsspoofer-gui
"lat, lon".
Start spoofing holds the device there; while running, move the pin and
hit Move to new coordinates to relocate without stopping.Stopping is immediate, and cleanup is robust: closing the window / Cmd-Q clears
the simulated location; a kill (SIGTERM/SIGINT) still kills the tunnel child;
and if the app is ever kill -9'd, the next launch reaps the orphaned
pymobiledevice3 process automatically.
Automation: set SPOOF_UDID=<udid> and/or SPOOF_START="lat,lon" in the
environment to preselect a device and auto-start spoofing on launch.
./package-dmg.sh # → dist/iOS-GPS-Spoofer-<version>.dmg
./package-dmg.sh --no-venv # lean build; app expects pymobiledevice3 on PATH
Builds iOS GPS Spoofer.app (generated icon, ad-hoc signed) and a drag-to-install
DMG. By default it bundles ./.venv inside the app, so the app finds
pymobiledevice3 on its own — it looks for Contents/Resources/venv, then
$PYMOBILEDEVICE3, then a .venv beside it, then $PATH.
The bundled venv's Python still references this machine's Homebrew Python, so the
default DMG runs on this Mac and Macs with the same brew install [email protected].
For a portable build use --no-venv and have users install pymobiledevice3
themselves. First launch of an ad-hoc-signed app: right-click ▸ Open.
Publishing a release (maintainer):
VERSION=1.0.0 ./package-dmg.sh
gh release create v1.0.0 "dist/iOS-GPS-Spoofer-1.0.0.dmg" \
--title "v1.0.0" --notes "iOS GPS Spoofer 1.0.0"
The Download link points at releases/latest, so it always
resolves to the newest published release.
# list paired devices
iosgpsspoof list
# spoof to a fixed point (Eiffel Tower). Holds until Ctrl-C, then restores real GPS.
iosgpsspoof spoof 48.8584 2.2945
iosgpsspoof spoof "48.8584,2.2945" # single-token form also works
# choose a device / link explicitly
iosgpsspoof spoof 37.3349 -122.0090 --udid 00008110-000815C10CD1801E --connection usb
# drive the device along a GPX track, looping forever
iosgpsspoof route ./drive.gpx --loop --timing-randomness 200
# manually clear a simulated location (e.g. if a previous run was killed hard)
iosgpsspoof clear
While spoof / route is running it:
Ctrl-C (or SIGTERM): stops the session, runs simulate-location clear,
exits. Pass --no-clear-on-exit to leave the fake location in place.| option | default | meaning |
|---|---|---|
--udid <id> |
first device | target device |
--connection any|usb|network |
any |
which link to use / require |
--transport native|tunneld|userspace |
native |
tunnel mechanism. native = no root (macOS). tunneld needs sudo pymobiledevice3 remote tunneld running. userspace = in-process, no root, slower |
--retry-interval <s> |
5 |
delay before re-establishing after a drop |
--no-clear-on-exit |
off | keep the fake location after exit |
--python-path <path> |
auto | explicit pymobiledevice3 binary |
native/tunneld transports. For iOS ≤ 16 you'd use
pymobiledevice3 developer simulate-location directly over usbmux.