Channels ▼
RSS

Tools

MonoTouch and the iPhone: The GPS and Compass Functions


Now that we have the outlets, we actually have to wire them up to their respective controls. To do this, first, select your App Delegate in the Document Window:

Figure 11

And then select the Connections tab in the Inspector window:

Figure 12

You can see all the Outlets we created earlier. To wire them up, drag from the little circle over to the control on the Document Designer Window, or the Document Window that you want to wire the Outlet up to:

Figure 13

Continue this until all the outlets are wired up to their appropriate controls:

Figure 14

Let's run this and make sure it looks right. Save and go back over to MonoDevelop and in the menu, choose "Run" and then click "Debug." You should have something like Figure 15.

Figure 15

All right, now that we have our interface all created, let's actually do some work.

Open up the Main.cs file, and in the AppDelegate class, add the following declarations to the class:


//---- declare vars
CLLocationManager _iPhoneLocationManager = null;
LocationDelegate _locationDelegate = null;

The first declaration is our CLLocationManager object. This class is the main point of use for the CoreLocation API.

The second declaration is our LocationDelegate. As mentioned before, the LocationDelegate is the strongly-typed delegate class that will handle location updates.

Next, create the custom LocationDelegate. To do this, add the following LocationDelegate code to the AppDelegate class:


//======================================
public class LocationDelegate : CLLocationManagerDelegate
{
	AppDelegate _app;

	public LocationDelegate (AppDelegate app) : base()
	{
		this._app = app;
	}

	//===============================
	public override void UpdatedLocation (CLLocationManager manager
		, CLLocation newLocation, CLLocation oldLocation)
	{
		this._app.txtAltitude.Text = newLocation.Altitude.ToString () + "meters";
		this._app.txtLongitude.Text = newLocation.Coordinate.Longitude.ToString () + "º";
		this._app.txtLatitude.Text = newLocation.Coordinate.Latitude.ToString () + "º";
		this._app.txtCourse.Text = newLocation.Course.ToString () + "º";
		this._app.txtSpeed.Text = newLocation.Speed.ToString () + "meters/s";
		
	}
	//===============================

	//===============================
	public override void UpdatedHeading (CLLocationManager manager, CLHeading newHeading)
	{
		this._app.txtMagneticHeading.Text = newHeading.MagneticHeading.ToString () + "º";
		this._app.txtTrueHeading.Text = newHeading.TrueHeading.ToString () + "º";
	}
	//===============================
}
//======================================

Let's take a quick look at this class. It has two methods that we override, UpdateLocation and UpdateHeading.

The UpdateLocation method is called when new location information is received, and from it we get things like location coordinates, altitude, and if we're moving, a course and heading.

The UpdateHeading method is called when new heading information is received (which comes from the compass), and from it we get our magnetic and true headings.

The class constructor takes an AppDelegate parameter, so that we can reference our outlets within our LocationDelegate. This is mostly for example purpose. You could instead raise an event in here and wrap your delegate up into another class if you wanted a more ".NETie" pattern.

Now that we have our delegate class in, let's add the following code to our FinishedLaunching method, before it returns out:


//---- initialize our location manager and callback handler
this._iPhoneLocationManager = new CLLocationManager ();
this._locationDelegate = new LocationDelegate (this);
this._iPhoneLocationManager.Delegate = this._locationDelegate;

//---- start updating our location, et. al.
this._iPhoneLocationManager.StartUpdatingLocation ();
this._iPhoneLocationManager.StartUpdatingHeading ();

And then add the following using directives to the top of the Main.cs file:


using MonoTouch.CoreLocation;

This code initializes our CLLocationManager and LocationDelegate objects, and then assigns our LocationDelegate to the CLLocationManager. Next, it tells the CLLocationManager to begin updating our location and heading info.

Our entire Main.cs file should now look like this:


using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MonoTouch.CoreLocation;

namespace Example_CoreLocation
{
	public class Application
	{
		static void Main (string[] args)
		{
			UIApplication.Main (args);
		}
	}

	// The name AppDelegate is referenced in the MainWindow.xib file.
	public partial class AppDelegate : UIApplicationDelegate
	{
		//---- declare vars
		CLLocationManager _iPhoneLocationManager = null;
		LocationDelegate _locationDelegate = null;
	
		// This method is invoked when the application has loaded its UI and its ready to run
		public override bool FinishedLaunching (UIApplication app, NSDictionary options)
		{
  // If you have defined a view, add it here:
  // window.AddSubview (navigationController.View);
				window.MakeKeyAndVisible ();
			
//---- initialize our location manager and callback handler
			this._iPhoneLocationManager = new CLLocationManager ();
	this._locationDelegate = new LocationDelegate (this);
			this._iPhoneLocationManager.Delegate = this._locationDelegate;
			
	//---- start updating our location, et. al.
			this._iPhoneLocationManager.StartUpdatingLocation ();
	this._iPhoneLocationManager.StartUpdatingHeading ();
			return true;
		}

	// This method is required in iPhoneOS 3.0
		public override void OnActivated (UIApplication application)
		{
		}
		
	//===============================
		public class LocationDelegate : CLLocationManagerDelegate
		{
			AppDelegate _app;
			public LocationDelegate (AppDelegate app) : base()
			{
			   this._app = app;
			}
		
	//===============================
		public override void UpdatedLocation (CLLocationManager manager
				, CLLocation newLocation, CLLocation oldLocation)
		{
		this._app.txtAltitude.Text = newLocation.Altitude.ToString () + "meters";
		this._app.txtLongitude.Text = newLocation.Coordinate.Longitude.ToString () + "º";
		this._app.txtLatitude.Text = newLocation.Coordinate.Latitude.ToString () + "º";
		this._app.txtCourse.Text = newLocation.Course.ToString () + "º";
		this._app.txtSpeed.Text = newLocation.Speed.ToString () + "meters/s";
				
		}
			//===============================
		
			//===============================
	public override void UpdatedHeading (CLLocationManager manager, CLHeading newHeading)
	{
	this._app.txtMagneticHeading.Text = newHeading.MagneticHeading.ToString () + "º";
		this._app.txtTrueHeading.Text = newHeading.TrueHeading.ToString () + "º";
	}
			//===============================
	}
	//===============================
	}
}

Now, if we run this in the simulator we should get something like Figure 16.

Figure 16

It takes a second or two for the CLLocationManager to acquire location and heading information and then it should get updated to the screen.

Now, because the simulator doesn't actually have access to location and heading information, it gives you simulated data, which returns the lat/long of Apple's headquarters in Cupertino, California, and made up data for the rest.

If you were to deploy this to an actual device however, you would get actual location information.

Congratulations, you now know how to use the CoreLocation API in MonoTouch! Now that we have this working, let's look at a few more considerations when using the it.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video