One of the key limitations of developing Web applications for iPhone is that you are not allowed to access the hardware on the device via the Web browser. For example, you cannot access the camera on the iPhone; neither can you access the accelerometer. This seriously limits the kinds of applications you can develop on the iPhone. One notable exception, however, is the support for tracking the location of devices, through a combination of GPS, Wi-Fi, and cellular triangulation.
In this article, I will take you through the geo-location classes available on the iPhone OS 3.0, and explore them to show you some of the interesting applications you can build.
Creating the Project
Using Dashcode, create a new Custom project and name it as LBS. For this project, you will create a web application for the iPhone and use it to display the current location using Google Maps. You will embed the Google Maps in your web application using the Google Maps API, which provides programmatic access to Google Maps using the various Javascript functions.
To use the Google Maps in your application, you need to apply for a free Google Maps API key (read the licensing page for more detailed information on the terms and conditions). You can sign up for a free Google Maps API key at: http://code.google.com/apis/maps/signup.html.
As the Google Maps API key is tied to the domain in which you are hosting your application, you need to ascertain the exact URL that you need to use for applying for the key. For testing in the iPhone Simulator, you can go to your project in Dashcode and press Command-R
to test the application. The URL in the iPhone Simulator should look something like this:http://localhost:12345/LBS/index.html
. In this case, you should use http://localhost:12345
when applying for the key.
You can also deploy the Dashcode project into your local Mac OS X web server (enabled through the Web Sharing feature in System Preferences). In this case, take note of the URL as shown in the Run & Share tab of Dashcode and use it when applying for the key. Finally, if you want to deploy it to a live web server, use the domain name of the web server. For example, if your web server domain is http://www.yourcompany.com
, then use “http://www.yourcompany.com” when applying for the key.
Once you have obtained the Google Maps API key, you will be ready to start embedding Google Maps in your application.
In Dashcode, edit the index.html
file of your project by adding the following element to the
element:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<head> <!--[if IE]><script>document.write('<base href="' + location.protocol + '//' + location.host + location.pathname.replace(//[^/]*$/, '/mobile/') + '"/>')</script><![endif]--> <base href="mobile/"> <script id="DC_baseScript">if(navigator.userAgent.indexOf('AppleWebKit/') == -1) document.write('<base href="' + location.protocol + '//' + location.host + location.pathname.replace(//[^/]*$/, '/mobile/') + '"/>')</script> <title>LBS</title> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.6"> <meta name="apple-mobile-web-app-capable" content="YES"> <link rel="apple-touch-icon" href="Images/WebClipIcon.png"> <link rel="stylesheet" href="main.css"> <script type="text/javascript" src="Parts/parts.js" charset="utf-8"></script> <script type="text/javascript" src="main.js" charset="utf-8"></script> <script src="http://maps.google.com/maps?file=api&v=2&sensor=true&key=YOUR_KEY_HERE" type="text/javascript"></script> </head> |
Note: Remember to replace the YOUR_KEY_HERE
placeholder with the key you obtained from Google.
In the element, add in the following lines of code to display the Google Maps as well as a
1 2 3 4 |
<center> <div id="map_canvas" style="width: 280px; height: 342px; "></div> <div id="text">Text</div> </center> |
So your element should look like:
1 2 3 4 5 6 7 8 9 |
<body onload="load();"> <div id="content"> <center> <div id="map_canvas" style="width: 280px; height: 342px; "></div> <div id="text">Text</div> </center> </div> <div apple-part="com.apple.Dashcode.part.webtext" class="apple-text apple-no-children" apple-default-image-visibility="hidden" apple-text-overflow="ellipsis" id="footer" apple-group="text" apple-style="part-height-dependent: true;"></div> </body> |
Displaying the Map
To show the Google Maps, you need to edit the main.js
file and add in the following lines:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
var map; function initializeMap() { if (GBrowserIsCompatible()) { //---shows the Google Maps in the DIV element--- map = new GMap2(document.getElementById("map_canvas")); //---set it to a particular location--- map.setCenter(new GLatLng(37.4419, -122.1419), 18); //---set the map type to Hybrid--- map.setMapType(G_HYBRID_MAP); } } function load() { dashcode.setupParts(); //---displays the map in the DIV element--- initializeMap(); } |
That's it! Press Command-R
to test the application on the iPhone Simulator. Figure 1 shows the Google Maps embedded in the web application.
Figure 1.Embedding Google Maps in your web application
Getting the Current Location
The iPhone OS 3.0 contains geographic location classes that web developers can access via Javascript. These classes are exposed via the Navigator
object. This object contains a read-only Geolocation
instance variable.
Let's now see how you can access these location data via your Dashcode project. In main.js
, add in the following statements:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
var map; var info; function load() { dashcode.setupParts(); //---displays the map in the DIV element--- initializeMap(); //---get the DIV element--- info = document.getElementById("text"); //---show the current position--- navigator.geolocation.getCurrentPosition(showMap); } function showMap(position) { //---display the current location--- info.innerText = "Lat: " + position.coords.latitude + " Lng: " + position.coords.longitude; //---set the map to the current location--- map.setCenter( new GLatLng(position.coords.latitude,position.coords.longitude), 18); } |
Essentially, the getCurrentPosition()
function retrieves the current position of the device. It takes in a callback function (named showMap()
in this example), which you will use to display the location on the Google Maps. You will also display the latitude and longitude of the current location in the div
element.
To test the application, press Command-R
in Dashcode. Notice that when the application starts up, you will be asked to grant permission to it to obtain your current location. Once permission is obtained, observe that the Google Maps will display a new location (see Figure 2). For the iPhone Simulator, it always displays "1 Infinite Loop, Cupertino, USA".
Figure 2.Testing the application on the iPhone Simulator
Monitoring Location Changes
Besides the ability to obtain the current location information, a more interesting capability is monitoring changes in location. This is useful if your user wants to view the map when he is on the move, such as when he is driving. To monitor for changes in location, you use the watchPosition()
function of the Geolocation
variable.
Add the following statements to the main.js
file. The following code adds a marker to the current location as well as displays the address of the current location (through reverse geo-coding - part of the functionalities provided by Google Maps).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
var map; var info; var marker; function load() { dashcode.setupParts(); //---displays the map in the DIV element--- initializeMap(); //---get the DIV element--- info = document.getElementById("text"); //---show the current position--- navigator.geolocation.getCurrentPosition(showMap); //---monitor the current position--- navigator.geolocation.watchPosition(panMap, handleError); } function panMap(position) { //---pans to the new location--- map.panTo(new GLatLng(position.coords.latitude,position.coords.longitude), 18); //---get the address of the location--- var geocoder = new GClientGeocoder(); //---perform reverse geocoding--- geocoder.getLocations( new GLatLng(position.coords.latitude, position.coords.longitude), showAddress); } //---shows error when monitoring location changes--- function handleError(error) { info.innerText = "Error: " + error; } function showAddress(response) { if (!response || response.Status.code!=200) { alert("Status Code: " + response.Status.code); } else { place = response.Placemark[0]; point = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]); map.setCenter(point,18); //---remove all existing markers--- map.clearOverlays(); //---add a marker--- marker = new GMarker(point); map.addOverlay(marker); //---display location details--- info.innerText = 'Lat: ' + place.Point.coordinates[1] + '. Lng: ' + place.Point.coordinates[0] + '. Address: ' + place.address + '. Accuracy: ' + place.AddressDetails.Accuracy + '. Country code: ' + place.AddressDetails.Country.CountryNameCode; } } |
Press Command-R
to test the application. To really test the application, you should use a real device (preferably an iPhone 3GS). As you move around, you will see the marker change its position. You will also see the address of the current location. For best effect, add the application to the Home Screen (see Figure 3). You can now view the map and the location in its entirety.
Figure 3.Adding to Home Screen so that you can run the application full screen
Summary
In this article, you have seen how to implement location-based services in your iPhone web applications. If you have implemented something similar, let us know! As usual, if you have new ideas for implementing location-based services, I would like to hear them.
7 Comments
Perfect post. Here’s a tool that helps create Map Mashup providing a step-by-step wizard that generates ready-to-deploy code on any website or blog http://blog.caspio.com/integration/announcing-the-new-and-improved-map-mashup-version-7/
Thanks for great information share ……..