Currently I\'m working on an App which geolocation capabilities are its most important feature. Actually we\'re very concerned about getting GPS values mocked up. I\'ve read
I don't believe it's possible to detect location simulators.
An easier way to fake location is to use an external bluetooth or serial connection to a GPS simulator that outputs NMEA sentences. You don't need a developer account although you do need an Android phone to run the simulator.
The iPhone will auto detect an external GPS and CLLocationManager
will use the external GPS sources in place of own internal GPS. It's really handy for lab testing of mapping and navigation apps.
To elaborate on @KennyHo answer, I found out that there is another difference between real and simulated locations feedback.
A simulated location, as I noticed, always returns this combination of values for these location properties/options:
horizontalAccuracy: 5
verticalAccuracy: -1
altitude: 0.000000
speed: -1
while a real location would give different combincation 99% of the time such as
horizontalAccuracy: 5
verticalAccuracy: 10
altitude: +/- 0.4243232
speed: -1
Note that it is possible for a simulated location to have a different combination than the above one but only if the user uses xcode Automation target test. However the user can only simulate a location to a signed app with a development identity (must own the app). This means nobody, except you, can fake a location with different altitude
or verticalAccuracy
to trick your app in xcode.
It is also possible to spoof iPhones with a software-defined radio and gps-sdr-sim from GitHub. You use gps-sdr-sim to generate I/Q files that contain GPS signals and use the SDR to transmit those samples over-the-air. This type of spoofing is much harder to detect.
There actually are 2 separate questions: (1) how to detect, and (2) how to prevent it?
[simulated locations] callback returns almost immediately after calling startUpdatingLocation, and then repeatedly called every exactly one second. Also the locations are all the same if we choose a fixed location. Here is an example:
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:48 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:49 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:50 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:51 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:52 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:53 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:54 Час: Індокитай
[real locations] It takes a few seconds (if first run) to call back and then randomly re-call. Also you can see the when significant changes among those locations even if you don't move at all. Here is an example:
location: <+10.77219361,+106.70597441> +/- 67.39m (speed -1.00 mps / course -1.00) @ 30.03.15 14:16:26 Час: Індокитай
location: <+10.77213011,+106.70591088> +/- 65.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:16:31 Час: Індокитай
location: <+10.77219507,+106.70587790> +/- 65.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:16:38 Час: Індокитай
location: <+10.77214753,+106.70587741> +/- 65.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:16:49 Час: Індокитай
Remind, it's just temporary solution to detect simulated locations. In the future, Apple may change the behaviour.
By the way, I've also tried to disallow simulate location on xCode at scheme: Unfortunately, it still allows simulated locations.
Some more issues you may know here. Hope it help.