Why You Should Lie To Google Maps
by Matthew Russell
Related link: http://maps.google.com
I think that we could all agree that Google Maps is one sweet application. Totally breaking the MapQuest norm, they threw in satellite/hybrid views, latitude/longitude navigation, cool AJAX-enabled scrolling, and an API (well, sort of) among other things. Who would have ever thought cartography could be so much fun?
Given that Google Maps isn't just your typical mapping experience, I've been pondering the possibilities of how it could be used to enhance desktop applications. Two apps that have already been enhanced by Google Maps come to mind right away: Address Book and Dashboard. In my opinion, both of these are great places for lacing in Google Maps, but I have to think that the best is yet to come. After all, when something becomes as pervasive as quickly as Google Maps did, it's just one of those commodities that people are going to start expecting to see everywhere -- not just on the web.
Fortunately for OS X developers, integrating Google Maps into your apps is cake. In fact, I almost decided not to even mention it -- but I couldn't resist because I thought the broader context of it all deserved some discussion.
Using WebKit, you can create a browser by writing only one line of code. Yes, ladies and gentlemen, it's true. Instead of reinventing the wheel here, however, take a look at the Mac DevCenter BYOB tutorial. When you build your own browser, you could go ahead and load up Google Maps right away, but it won't be a very friendly user experience. You'll be told that your browser isn't supported, and if you load the page anyway, you'll get slammed with intermittent messages like this one time and time again. Eventually, you'll risk losing your patience. Let's not go there.
"But Safari uses WebKit and it works fine on Google Maps. Why doesn't WebKit work when I try," you ask. Well, here's the thing: browsers send in a UserAgent string to each web server they talk to as part of the normal chatter that goes on. If you want to know what this string looks like, you can type this into your browser's address bar to see for yourself:
If you don't get a response, wrap it up in a simple HTML page and load it in the browser to get something back. It should look like this if you're using Safari:
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412.7 (KHTML, like Gecko) Safari/412.5
Your homebrewed browser, on the other hand, gives you something like this:
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412.7 (KHTML, like Gecko)
You can see that Safari adds a little bit to the end, and Google Maps doesn't appreciate our homebrewed browser's non-compliance. Did you really think that Big Brother was the only one watching?!? Fortunately, we can care of things very easily, but we'll have to tell a lie to do it. Here goes, (ok, so it's more of a spoof than a lie.)
In the method call,
webWindowis an outlet to your WebView in Interface Builder, and
UserAgentStringis an NSString containing a UserAgent value like the one from Safari that Google Maps supports.
From here, you could do a lot of neat things to integrate Google Maps into your application. Remember that your user interface doesn't have to remotely resemble a web browser at all. Instead, you could load the content in the
WebViewusing an interface of your own choosing or through some other automated process by manipulating the query string. For example, if you wanted to load a map of Springfield, VA, pass the WebView the value "http://maps.google.com/?q=springfield+va". For more complex examples of URLs with custom query strings, click "Link to this page" in the sidebar of Google Maps.
Now, go give it a try.
What are some examples of how you would like to see Google Maps laced into desktop applications?
MapQuest and globeXplorer
I just got a friendly message from someone with some info in it that I wasn't aware of (I must have been too busy trying to get from point A to point B to notice this -- which is entirely possible -- or else it just wasn't all that well publicized.)
An easier solution...
Instead of concocting a whole new UserAgent string, just specify the application name to be inserted into the UserAgent: