Home > Development, MacOSX > Desktop Core Location

Desktop Core Location

September 8th, 2008

Update 18/Feb/09 @ 19:45 EST: Source code is on BitBucket.org:

hg clone http://bitbucket.org/philippec/desktopcorelocation

Update 5/Feb/09 @ 12:43 EST: It appears that Apple may implement CoreLocation in their next generation desktop OS. Excellent!.

Update 8/Sep/08 @ 22:40 EST: The license is MIT. Share and enjoy!.

Update 8/Sep/08 @ 21:45 EST: This is an IronCoder entry, and is essentially a hack. I’m working on figuring out a license.

My IronCoder entry for c4[2]: a clean-room implementation of Apple’s CoreLocation.framework, complete with sample application.

http://developer.casgrain.com/files/DesktopCoreLocation.zip

Description

This is a clean-room implementation of Apple’s CoreLocation framework that is part of the iPhone SDK.

It uses Apple’s own headers, which are installed when you install the iPhone SDK, as the interface, and implements all the functionality of CoreLocation in an embeddable framework.

It can be made a system-wide framework buy changing its executable path from @loader_path/../Frameworks/ to /Library/Frameworks.

The Desktop and Phone sample applications are very similar: they both demonstrate using CoreLocation.framework.

How it works

The framework figures out your current, internet-facing IP address using whatismyip.com. It then uses basic IP Geolocation web services to extract latitude and longitude. Results are cached 30 days for each IP address.

There are certainly other IP geolocation services (for instance, SkyHook Wireless) but they required a paid license.

Paranoïa

In keeping with the theme, you can drop a file called unauthorizedApps in /Library/Documents/WebServer/clbl/ and start your webserver. You can then edit the file at will to deny a particular app the use of CoreLocation.

Contents

PhoneLocation/PhoneLocation.xcodeproj
Sample application that demonstrates using CoreLocation on the iPhone/iPod Touch.
Build and go, it will find your current location (which, in the Simulator, is 1, Infinite Loop, Cupertino, CA). Press the “Show Me” button to go to these coordinates in Google Maps.

DesktopLocation/DesktopLocation.xcodeproj
Sample application that demonstrates using CoreLocation on the Desktop. It uses the Desktop CoreLocation framework in exactly the same manner as PhoneLocation, but the results are pulled from my version of the framework.
Press the “Show Me” button to go to these coordinates in Google Maps.

CoreLocation/CoreLocation.xcodeproj
Stand-alone, embeddable framework

Requirements

  • MacOSX 10.5
  • Latest iPhone SDK. Does not contain any Apple proprietary information.
  • Internet connexion
Categories: Development, MacOSX Tags:
  1. September 8th, 2008 at 10:42 | #1

    It might be interesting to extend the implementation to support a GPS device, if available.

  2. September 8th, 2008 at 10:47 | #2

    Definitely! This is a one-weekend hack (the way IronCoder should be). Feel free to improve on it!

  3. September 8th, 2008 at 18:04 | #3

    This is an awesome idea. Good work!

    -W

  4. September 8th, 2008 at 18:32 | #4

    Thanks! Everybody please be sure to file a Radar with Apple to ask for Core Location to be supported on the desktop (or really, where it’s really useful is a laptop). If enough people explain how useful it can be for road-warriors, we might get a very accurate official implementation in Snow Leopard…

  5. September 8th, 2008 at 18:49 | #5

    Very cool, great job!

  6. September 8th, 2008 at 18:52 | #6

    What license has this been released under? I didn’t see it in the zip anywhere.

  7. September 8th, 2008 at 19:05 | #7

    Philippe,

    I work for Skyhook and just wanted to correct your statement that we require a paid license. We offer an SDK to any developer who wants to integrate it into an application. You can get the SDK here: http://www.skyhookwireless.com/developers

    We think this is a great project and we are happy to help out in any way we can. Feel free to email me directly — rsarver skyhookwireless com — if you have any questions.

    Best, rs

  8. Erik
    September 8th, 2008 at 20:26 | #8

    I’m curious about the pattern used in the CoreLocation implementation files – specifically, the internal object that is being held on to by instances of those classes. What’s going on here – is it for thread-safety, or something else, or is it just a matter of programming style? Finally, is it common in Cocoa, or is this a somewhat unusual usage?

  9. September 8th, 2008 at 20:42 | #9

    Erik,

    It’s one way to do a public interface. Essentially, it’s an Abstract Factory (see http://en.wikipedia.org/wiki/Abstract_factory_pattern ). Your implementation of the class must then implement all that is declared, and usually a bit more (private stuff).

    You could do the same thing with protocols, or (in C++) with pure virtual classes, but in this case the design was dictated by Apple’s headers. I just followed their lead.

  10. September 8th, 2008 at 20:45 | #10

    Jesse,

    Thanks for reminding me about the license. I’m working on it.

  11. September 9th, 2008 at 02:16 | #11

    Why not use the iPhone as GPS device and build an IP connection using CoreLocation on the phone sending the data to the DesktopCoreLocation framework. Could be done in various stages like the phone does with carrier locating when GPS is not available yet.

  12. September 9th, 2008 at 05:47 | #12

    Tom,

    The whole thing came about because I don’t have an iPhone and if you use CoreLocation in the Simulator (see PhoneLocation.xcodeproj in the zip file), it reports your location as 1, Infinite Loop, Cupertino, CA…

  13. September 9th, 2008 at 05:50 | #13

    Your presentation was great! Go Canada!

  14. September 9th, 2008 at 10:16 | #14

    You couldn’t give us an Application demo without having to build it?

  15. September 9th, 2008 at 12:39 | #15

    msr:

    That’s correct. The projects build out of the box, and adding a built app to the zip file more than doubles its size.

  16. Johannes Fortmann
    September 12th, 2008 at 07:56 | #16

    Some notes:
    - in performSelectorOnMainThread:withObject:, both the receiver and the object are retained. That means you don’t have to do the retain/release dance you’re currently doing.
    - your internal object has all its properties marked “assign”. That’s almost certainly not what you want. Specifically, the delegate should be assign, all others should be retain or copy. You’ll have to add a dealloc method, but the rest of your code will be much simpler (e.g. in updateLocation: you won’t have to worry about that ipAddress var which is currently only valid by sheer luck).
    Generally, you want to copy any possibly mutable objects (specifically strings), retain all noncopyable objects (like NSThread), and assign only delegates, data sources and the like.
    - likewise, is there any reason internal isn’t a property?

    HTH, and nice work!,
    Johannes

  17. September 12th, 2008 at 11:27 | #17

    If you’re running it on a system that isn’t online at the moment, you could fall back on the less precise “nearest major city” stored by Mac OS X:

    BOOL GetCityLatLong(Location *outLocation) {
    id city = [[NSUserDefaults standardUserDefaults] objectForKey: @”com.apple.TimeZonePref.Last_Selected_City”];
    if (city && [city isKindOfClass: [NSArray class]] && [city length] >= 2) {
    /* First two elements are the L/L. */
    if (outLocation) {
    outLocation->latitude = [[city objectAtIndex: 0] doubleValue];
    outLocation->longitude = [[city objectAtIndex: 1] doubleValue];
    }
    return YES;
    }
    return NO;
    }

  18. September 12th, 2008 at 11:29 | #18

    And, I should say, you can listen for @”NSSystemTimeZoneDidChangeDistributedNotification” distributed notifications and update your reported location when they occur.

  19. September 24th, 2008 at 05:45 | #19

    Johannes,

    Thanks for taking some time and looking at my code! I guess my inexperience with these newfangled properties shows a little…

    For performSelectorOnMainThread:withObject:, you are correct. The retain/release cycle was unnecessary, so I removed it.

    In the case of the internal object’s properties, I followed your advice about copy/retain, but I wonder why I would need a -dealloc method. Shouldn’t @synthesize do all of this for me, call -release when a property is retain for instance? Furthermore, properties that are not NSObjects should be assign, as you can’t copy or retain simple types (float, int…).

  20. April 2nd, 2010 at 09:23 | #20

    Тоже думаю добавить в закладки, интересный блог.

Comments are closed.