Some good news and some less good news today (it seems they always come together :-0).
I have been playing around intensively trying to hook into the CoreLocation framework by using the MobileSubstrate platform. Rodrigo, a customer from Portugal, dropped me an email two weeks ago with some very useful source code and a link for a MobileSubstrate tutorial on using MobileSubstrate to trick the Springboard.
Rodrigo pretty much figured out how to feed the CoreLocation framework coordinates and accuracy data. I decided to dig in a little more and managed to also feed the CoreLocation framework fake (generated by a random number generator) altitude, speed and heading data. It was a little bit tricky to get the speed and heading in as it required upgrading the Toolchain to 2.2 (I was at 2.0.1, but am currently at 2.2). It looks like Saurik has updated his instructions for building the 2.x Toolchain and it seems to be pretty straightforward now assuming you follow instructions as outlined (I have done it a few times now and have gotten the hang of it :-)
So what have we been able to do? I installed a bunch of free AppStore apps on my iPhone 2G that are GPS related: Google Earth, GPSLite, Beacon, Speedometer, GPS Tracker, GPS Ally, GPS-R and Trailguru.
Here are the most interesting ones:
- GPS Tracker: this app has a nice readout on its screen of the location data (see top left screenshot above) and was therefore most helpful in trying to figure out the hooks. I signed up for a device key on the InstaMapper website so that my location data could be uploaded to their site. Due to the override of the location accuracy, the GPS tracker shows "tracking" on its screen (it doesn't matter what you set the slider at), but it only seems to send the location data to their servers once (right after I start the application). The data on the iPhone screen is however updated continuously.
- Google Earth: this app also displays the fake latitude and longitude data after pressing the little bulls eye in the lower left corner. Also here, the data is only updated once (when you press the bulls eye). Make sure to turn the latitude/longitude display on under the settings in Google Earth. The altitude shown is actually not related to the CoreLocation altitude as it is the altitude for the zoomlevel of the satellite image that is active.
- GPS Ally: this app shows the current location data on its screen as well (see top right screenshot above), but here also, the data is only updated once (after starting the app). You can re-update it manually by hitting the "Update On/Off" button in the lower left corner twice.
- Trailguru: this app also shows the latitude, longitude and altitude/elevation (see the bottom center screenshot above), but doesn't seem to use the speed data (probably because it was written for firmware < 2.2). Here again, the actual app doesn't seem to use the changing CoreLocation data even though the values are changing on its screen. An interesting thing is however that if you press on the "Map" icon at the bottom, the center of the map does move around according the the fake data the CoreLocation framework is fed.
So now for the less good news...
I am currently stuck as I haven't figured out how to tell an app that new CoreLocation data is available so that e.g. the GPS tracker app will continuously use the new data and send a new point to its servers. The same for Google Earth, GPS Ally and Trailguru.
What I think is that we need to do something with the CoreLocationManager framework and/or the CoreLocationManagerDelegate framework and their delegates. We would need to somehow tell the CoreLocationManager object of the app that the CoreLocation object (which I am succesfully feeding fake location data) has a new data set so that it will actually use that new data.
So I am counting on some help from you in getting this figured out as I have pretty much run out of ideas.
You can do some reading around in Apple's documentation and on the forums to see if we can find what needs to be done.
I have also uploaded the source code for the CoreLocation hook here. If you wish to try it out, make sure to have Toolchain 2.2 installed (if you have Toolchain < 2.2 installed, just comment out the speed hooks and any other ones that the compiler complains about in the source code). Also make sure to install MobileSubstrate through Cydia on your device and also put the libsubstrate.dylib file into your filesystem library directory on your desktop so the compiler can find it. Make sure to "ldid -S" the ExampleHook.dylib file after it is put in /Library/MobileSubstrate/DynamicLibraries on the phone. You can take a look at the Makefile as most of the process is automated in it.
If it turns out to be possible and we do find the solution, it will be great news as it means that we can use our iGPS360 module with the majority of the AppStore apps!