iPhone/iPad Development With MonoTouch – A Tutorial

by on October 30, 2012 10:52 am

What if your boss came to you today and said: “We need to build a mobile iPhone/iPad application for our company’s legacy desktop application.”

After the excitement of finally working on a mobile application subsides, you might begin to wonder if you’ve actually just gotten yourself down a rabbit hole. 

As a .NET development shop, you realize that you don’t have Objective-C programming skills. Plus the requirements of the mobile application must have the same business rules as the desktop version. Since the user would like the application as soon as possible, you don’t have the time to learn and rewrite the current desktop application into Objective-C.

Don’t panic, MonoTouch by Xamarin is here to help you.


MonoTouch allows you to reuse your C# skills to build iPhone and iPad applications. Unlike HTML5 options, MonoTouch is natively compiled to the iOS platform. This native compile allows you full access of Apple’s API and UI. Some of MonoTouch’s key features include:

  • MonoDevelop – Just like Visual Studio, MonoDevelop is an IDE that provides code assist, project management, and debugging tools.
  • C# – The features of the language Type-Safety, Dynamic Constructs, Functional Constructs such as Lambdas, LINQ, Automatic Garbage Collection are all available.
  • Inter-operability – Third party libraries that are written in Objective-C or C/C++ can be called directly from MonoTouch.
  • Re-usability – The common background business logic can be reused in Windows 7 & 8 mobile, and Mono for Android mobile applications.


In order for you to use MonoTouch, an Apple computer running Snow Leopard (or later) is required. Since the application is compiled natively, Apple’s Xcode SDK is required. The Xcode development enviroment also provides the iOS emulator for testing the application. If your manager doesn’t want to spend the entire IT budget on your new Apple Macbook, a cheap alternative is the Mac Mini.

MonoTouch is free to download, but it is limited to only running the application within the iOS emulator. If you want to install applications on a iPhone or iPad, then you will need to buy a license.

Download and install the following: 

  • Apple’s Xcode from either the Mac App Store or Apple’s iOS developer website
  • MonoTouch from Xamarin

First Application

Instead of doing a “Hello World” application for the millionth time, we’ll work on an example application that will retrieve the current weather conditions based on location.

A working example can be downloaded from the Keyhole’s GitHub repository: https://github.com/in-the-keyhole/khs-blog-examples.git

After clicking the MonoDevelop IDE icon, lets begin with starting a new MonoTouch project:

After clicking the OK button, a single view template project has been created for you. As a Visual Studio developer, the MonoDevelop environment should look like an old friend. Solutions, projects, files and references are laid out the same way as Visual Studio.

Let’s take a close look at the template that MonoTouch created for you:

  • Main.cs – This file is the starting point of the application.
  • AppDelegate.cs – This file contains the main application class that is responsible for listening to events.
  • CurrentTemperatureViewController.cs – This is where you will write the code to interact with the screen.
  • CurrentTemperatureViewController.designer.cs – This class is automatically updated when you add controls to the screen from XCode IDE.
  • CurrentTemperatureViewController.xib – This file is the screen design as describe by XML.
  • Info.plist – This file contains properties for the application such as application name and target platform

Building the Screen Layout

Double click the CurrentTemperatureViewController.xib file within the project. This will open Xcode and visually display the screen layout. Using the Xcode editor, you can lay out the controls by dragging them from the object list to the screen.

In our example, we are going to add four labels and a button. To learn more about how to use Xcode, visit Apple’s Developer site.

From the object pane of Xcode, drag and drop the UILabels and UIButton to the screen area.

Wire Controls

Apple provides Outlets and Actions that implements the interaction needed for our two controls.

  • Outlets – Outlets work exactly the same as properties in .NET applications.
  • Actions – Actions work in the same manner as the command pattern does for .NET. Actions allow the developer to wire many controls to the same method.

To add an Outlet or Action: change the Xcode view mode to Assistant Editor, which will split the editor screen. While holding the CTRL key, drag the controls from the view to any space in the code after the @interface definition. A popup will be displayed asking for the type and name. Select Outlet and give it a name. Also for the button, we will create an Action for the Touch Up Inside event.

For more detail instructions on adding Outlets and Actions, I recommend visiting Xamarin’s Hello World example.

Now that controls have been wired up to the screen, we now need to start coding the business logic for the windows.

Reusing Business Logic

One of the advantages of using Monotouch is that the business logic that you already wrote for those legacy applications can be reused.  This also includes most 3rd party libraries that are written for .NET.  The domains, validations, and services can be used in the Monotouch application.

In this example, I will create two simple domains Location and Weather.  Even though I’m creating the code within the Monotouch project, for better reusability the code should be in its own library.  This way it can be shared by both the legacy application and Monotouch.

public class Location
	public string City { get; set; }
	public string State { get; set; }
	public string Zipcode { get; set; }



public class Weather
   public string Temperature { get; set; }
   public string Condition { get; set; }
   public string Humidity { get; set; }
   public string Wind { get; set; }

Now that the domains have been created, I will create a simple service that will call the Yahoo Weather API.  Our service will pass the zip code to the Yahoo Weather API and then parse the current conditions from the xml response.

public class YahooWeatherService : IWeatherService
   private const string URL_YAHOO_WEATHER = "http://weather.yahooapis.com/forecastrss?p={0}";
   private readonly string[] DIRECTIONS = {"N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW", "NW","NNW"} ;
   public Weather CurrentWeather (string zipcode)
      string url = string.Format(URL_YAHOO_WEATHER, zipcode);
      return ProcessService(url);
   private Weather ProcessService (string url)
      Weather weather = null;
      XmlDocument doc = new XmlDocument ();
      // Load data
      doc.Load (url);
      // Set up namespace manager for XPath
      XmlNamespaceManager ns = new XmlNamespaceManager (doc.NameTable);
      ns.AddNamespace ("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0");
      // Get current forecast with XPath
      XmlNode condNode = doc.SelectSingleNode ("/rss/channel/item/yweather:condition", ns);
      XmlNode astrNode = doc.SelectSingleNode ("/rss/channel/yweather:atmosphere", ns);
      weather = new Weather {
         Condition = condNode.Attributes["text"].Value,
         Temperature = condNode.Attributes ["temp"].Value,
         Wind = getWindDescription(doc, ns),
         Humidity = astrNode.Attributes["humidity"].Value
      return weather;
   private string getWindDescription (XmlDocument doc, XmlNamespaceManager ns)
      XmlNode windNode = doc.SelectSingleNode ("/rss/channel/yweather:wind", ns);
      var speed = windNode.Attributes["speed"].Value;
      var degreeString = windNode.Attributes["direction"].Value;
      float degree = 0;
      float.TryParse(degreeString, out degree);
      int index = (int) ((degree / 22.5) + 0.5);
      index = index % 16;
      string name = DIRECTIONS[index];
      return string.Format("Wind: {0} at {1}mph", name, speed);

Location and Geocode

Now that the business and service logic are done, we need to retrieve the GPS coordinates and the location.  The nice thing about using Monotouch is that the classes are named the same as Apple’s own classes.

First, let’s create a delegate class that will be used by the GPS. This class will be extended from the CLLocationManagerDelegate class. The one method that will be overridden is the UpdateLocation. When the GPS updates the coordinates, the UpdateLocation method is called with the new values. The CLGeocoder class method ReverseGeocodeLocation will take the coordinates from the GPS and return the address information to the handler:

public class LocationDelegate : CLLocationManagerDelegate
    private CLGeocoder geocoder = null;
    private IWeatherService WeatherService {
        get { return new YahooWeatherService (); }

    private CurrentTemperatureViewController screen;
    public LocationDelegate (CurrentTemperatureViewController screen) : base()
        this.screen = screen;

    public override void UpdatedLocation (CLLocationManager manager, CLLocation newLocation, CLLocation oldLocation)
        if (screen.CurrentWeather == null)
            geocoder = new CLGeocoder ();
            geocoder.ReverseGeocodeLocation (newLocation, ReverseGeocodeLocationHandle);

    public void ReverseGeocodeLocationHandle (CLPlacemark[] placemarks, NSError error)
        Location loc = new Location();
        for (int i = 0; i < placemarks.Length; i++) {
            loc.Zipcode = placemarks [i].PostalCode;
            loc.City = placemarks[i].Locality;
            loc.State = placemarks[i].AdministrativeArea;

        if (screen.CurrentWeather == null)
            screen.CurrentWeather = WeatherService.CurrentWeather(loc.Zipcode);
            screen.CurrentLocation = loc;


Controller and AppDelegate

We are now on the home stretch for running the application. The last thing we need to do is set up the controller class.

The CurrentTemperatureViewController class was created by the MonoTouch template wizard. The ViewDidLoad method is called when the view is about to load, and before the constructor is called. In this method, we are going to initialize the CLLocationManager and start the GPS location updates. The DisplayScreen is called from the LocationDelegate that we created earlier. The method will copy the values to the controls that we created on the screen layout. The Refresh method is called during the click event of the refresh button.

public partial class CurrentTemperatureViewController : UIViewController
   // Initialize a location manager
   private CLLocationManager iPhoneLocationManager = null;
   private Weather CurrentWeather { get; set; }
   private Location CurrentLocation { get; set; }
   public CurrentTemperatureViewController () : base ("CurrentTemperatureViewController", null)
   public override void ViewDidLoad ()
      base.ViewDidLoad ();
      // Perform any additional setup after loading the view, typically from a nib.
      iPhoneLocationManager = new CLLocationManager();
      iPhoneLocationManager.Delegate = new LocationDelegate(this);
   public void DisplayScreen ()
      lblTemp.Text = CurrentWeather.Temperature + "ツー F";
      lblCondition.Text = CurrentWeather.Condition;
      lblWind.Text = CurrentWeather.Wind;
      lblCityState.Text = string.Format("{0}, {1}", CurrentLocation.City, CurrentLocation.State);
   public override void ViewDidUnload ()
      base.ViewDidUnload ();
      // Clear any references to subviews of the main view in order to
      // allow the Garbage Collector to collect them sooner.
      // e.g. myOutlet.Dispose (); myOutlet = null;
      ReleaseDesignerOutlets ();
   public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
      // Return true for supported orientations
      return (toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown);
   partial void Refresh(NSObject sender)
      CurrentWeather = null;
      lblTemp.Text = "";
      lblCondition.Text = "";
      lblWind.Text = "";
      lblCityState.Text = "";

The last thing to do is set up the singleton AppDelegate class. This class will initialize the application during startup and setup any notifications. The main method to be implemented is the FinishedLaunching method, which will define the root controller. One caveat of the FinishedLaunching method is that code has to complete within 15 seconds or the application will shutdown. If you need a long running service to retrieve data, create a new thread for the task.

[Register (&quot;AppDelegate&quot;)]
public partial class AppDelegate : UIApplicationDelegate
   // class-level declarations
   UIWindow window;
   public override bool FinishedLaunching (UIApplication app, NSDictionary options)
       window = new UIWindow (UIScreen.MainScreen.Bounds);
       window.RootViewController = new CurrentTemperatureViewController ();;
       window.MakeKeyAndVisible ();
       return true;

Now that this is complete, we can run the application and see something like the following:

Final Thoughts

As you can see this is a simple application, but it gets you an idea of what Monotouch can bring to the table.  So when the boss asks about exposing that legacy application to mobile platforms, you can be confident about implementing the application.

In a later blog post, I will discuss in more detail navigation and the use of third party libraries. In the meantime, go to the Xamarin website and review the examples. It has a plethora of information from code snippets to guides. Good luck!

— Mark Fricke, asktheteam@keyholesoftware.com

  • Share:

5 Responses to “iPhone/iPad Development With MonoTouch – A Tutorial”

  1. David says:

    Very helpful, thanks… David

  2. iPhone/iPad Development With MonoTouch – A Tutorial…

    Thank you for submitting this entry – Trackback from MonoTouch.Info…

  3. […] iPhone/iPad Development With MonoTouch – A Tutorial […]

  4. […] my previous article, I gave a tutorial on how we can use Xamarin.iOS (formally known as Monotouch) to build iOS mobile […]

  5. Antoinette says:

    Wonderful post! We are linking to this great article on our website.
    Keep up the good writing.

Leave a Reply

Things Twitter is Talking About
  • We <3 consulting & we <3 development! Want proof? We created #GrokOla, a tool for clients to ask our team high-level development questions.
    April 26, 2015 at 4:04 PM
  • Want to write a single page app with ExtJS? View @zachagardner's video tutorial series for guiding #ExtJS principles: http://t.co/q4ctOYduNb
    April 25, 2015 at 12:47 PM
  • It's Friday! Nothing better than an impromptu Keyhole team happy hour @75thStBrewery. Great way to kick off the weekend. #loveourteam
    April 24, 2015 at 4:00 PM
  • .@Jinaljay transitioned to #Java from .NET & needed to switch IDEs. Tips that helped her in the switch to #eclipse - http://t.co/wbx9qGcbhX
    April 24, 2015 at 2:30 PM
  • Do you like to lay #JavaScript code just as much as you love to manage dev teams? Apply to be a Lead JS Dev with us - http://t.co/TIKNFUZj4q
    April 24, 2015 at 12:16 PM
  • Know Your IDE: #Eclipse http://t.co/wbx9qGcbhX With tips and shortcuts to make it easier to use.
    April 24, 2015 at 11:27 AM
  • #Java is OO but contains non-object primitives. Autoboxing feels more like a band-aid. Do primitives need to go? http://t.co/A8ChCBqmle
    April 24, 2015 at 10:59 AM
  • .@racingcow we're so glad you're interested in attending #KCDC15! Just follow us and we will DM you the code to save 10% off your ticket!
    April 23, 2015 at 4:25 PM
  • Rapid #appdev has a bad rep, but there are ways to bring development time down the right way. Don't Fear the Rapid - http://t.co/8CKhAzE9jJ
    April 23, 2015 at 2:30 PM
  • #JavaScript debugging is tough - every technique you have in your toolbelt can help! Time-Oriented #Debugging - http://t.co/n0JrRPrWHt
    April 23, 2015 at 10:20 AM
  • 4 Creative Ways to Test Your Code in Production - http://t.co/OijrRetTNA
    April 23, 2015 at 9:13 AM
  • Code For Maintainability So The Next Developer Doesn't Hate You - http://t.co/iG2wW2rSWj Eight helpful tips to do so.
    April 23, 2015 at 6:30 AM
  • Big news - we've released a demo version of #GrokOla open to the public. Try out its features & capabilities - http://t.co/O4ladoeLhk
    April 22, 2015 at 2:50 PM
  • Here's a free primer for ​implementing a RESTful API using #SpringMVC ​- http://t.co/JWvqeg3SST #GrokOla
    April 22, 2015 at 2:20 PM
  • Interesting article with a neat open source tool - osquery. Why Sharing Your Security Secrets Is a Good Thing http://t.co/Tcpt27ibjI
    April 22, 2015 at 8:50 AM
  • ICYMI: Free #GrokOla development primer. Get to know #Java Lambdas - http://t.co/D2iLLj8mph
    April 21, 2015 at 4:31 PM
  • We've been releasing some free #Grokola tutorials. See them all in one spot - http://t.co/WDt5fVSwaA #JavaScript #Backbonejs #nodejs #java
    April 21, 2015 at 2:30 PM
  • Are you a planner? Then you'd better get your @kc_dc tickets! Tweet us for a '10% off your ticket' #KCDC15 code. We're excited to sponsor!
    April 21, 2015 at 12:15 PM
  • #Netty can handle multiple traffic types concurrently, like #WebSockets & HTTP over the same port at the same time: http://t.co/TIufQDCCiC
    April 21, 2015 at 10:04 AM
  • There's a new post on the Keyhole blog from @Jinaljay - Know Your IDE: #Eclipse http://t.co/wbx9qFUAqp
    April 20, 2015 at 10:27 AM
Keyhole Software
8900 State Line Road, Suite 455
Leawood, KS 66206
ph: 877-521-7769
© 2015 Keyhole Software, LLC. All rights reserved.