iOS Development using MonoTouch Cookbook

By Dimitris Tavlikos
    Advance your knowledge in tech with a Packt subscription

  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Development Tools

About this book

MonoTouch brings the amazing revenue opportunities of Apple’s billion dollar app store to C# and .NET developers.

This cookbook leaves no stone unturned, providing you with practical recipes covering user interfaces, data management, multimedia , web services, and localization, right through to application deployment on the app store.

Whatever the area of MonoTouch iOS development you need to know about, you will find a recipe for it in this cookbook. Minimum theory and maximum practical action defines this book. It is jam packed with recipes for interacting with the device hardware, like the GPS, compass and the accelerometer. Recipes for those all important real world issues such as designing the UI with the integrated designer introduced with Xcode 4. It is the essential cookbook for C# and .NET developers wanting to be part of the exciting and lucrative world of iOS development.

Publication date:
December 2011
Publisher
Packt
Pages
384
ISBN
9781849691468

 

Chapter 1. Development Tools

In this chapter, we will cover:

  • Installing pre-requisites

  • Creating an iPhone project with MonoDevelop

  • Interface builder

  • Creating the UI

  • Accessing the UI with outlets

  • Adding actions

  • Compiling

  • Debugging our application

 

Introduction


One of the most important things professionals care about is the tools that are required to perform their work. Just as carpenters need a chisel to scrape wood, or photographers need a camera to capture light, we as developers need certain tools that we cannot work without.

In this chapter, we will provide information on what Integrated Development Environments (IDEs) and Software Development Kits (SDKs) are needed to develop applications for iOS, Apple's operating system for the company's mobile devices. We will describe what every tool's role is in the development cycle and step through each one's important features that are essential to develop our first application.

The tools needed to develop applications for iOS are the following:

  • An Intel-based Mac computer running Snow Leopard (10.6.*) or Lion (10.7.*) operating system: The essential programs we need cannot be installed on other computer platforms.

  • iOS SDK version 3.2 or higher: To be able to download iOS SDK, a developer must be registered as an Apple developer. iOS SDK, among other things, includes two essential components.

    • Xcode : Apple's IDE for developing native applications for iOS and Mac with the Objective-C programming language.

    • iOS Simulator : An essential program to debug iOS apps on the computer, without the need of a device. Note that there are many iOS features that do not work on the simulator; hence, a device is needed if an app uses these features.

    Both the registration and SDK download are free of charge from Apple's Developer portal (http://developer.apple.com). If we want to run and debug our applications on the device or distribute them on the App Store, we need to enroll with the iOS developer program, which requires a subscription fee.

  • Mono for Mac: Mono is an open source implementation of Microsoft's .NET framework. It provides a multi-platform set of tools, libraries, and compilers to develop .NET applications on all mainstream computer operating systems (Linux, Mac, and Windows). We need the latest Mac installer, available from Mono's website.

  • MonoTouch: MonoTouch is an SDK, based on Mono. It provides .NET developers with the ability to develop applications for iOS, using C# as a programming language. A free evaluation version is available on the MonoTouch website (http://ios.xamarin.com), which has all the features of the commercial versions to debug and run applications on iOS Simulator, without an expiration limit. For deploying applications on a device, or distributing on Apple's App Store, purchasing a commercial license is required.

  • MonoDevelop: MonoDevelop is an open source IDE for .NET development. It provides developers with lots of features, such as code completion, database browsing, debuggers, and so on. The Mac version provides iOS project templates and MonoTouch integration.

This chapter will also describe how to create our first iPhone project with MonoDevelop, construct its UI with Interface Builder, and how to access the application's user interface from within our code, with the concepts of Outlets and Actions .

Last but not least, we will learn how to compile our application, the available compilation options we have, and how to debug on the simulator.

 

Installing pre-requisites


Information on how to download and install the necessary tools to develop with MonoTouch.

Getting ready

We need to download all the necessary components on our computer. The first thing to do is register as an Apple Developer on http://developer.apple.com. The registration is free and easy and provides access to all necessary development resources. After the registration is confirmed through e-mail, we can log in and download the iOS SDK from the address https://developer.apple.com/devcenter/ios/index.action#downloads. At the time of writing, Xcode's latest version is 4.2, and iOS SDK's latest version is 5.0.

At times, when Apple introduces beta versions of its components, they are made available through its portal. Although everyone registered can download and use these components, our already installed version of MonoTouch might not work correctly with the beta version of iOS SDK or Xcode. So, this must be taken into account when downloading and installing new beta versions from Apple Developer portal.

How to do it...

To prepare our computer for iOS development, we need to download and install the necessary components in the following order:

  1. Xcode and iOS SDK on OS X Snow Leopard: After downloading the image file, mount it, and in the window that will pop up, double-click on the Xcode and iOS SDK icon to start the installation. For the installation to proceed, it is necessary to read and accept the two licensing agreements that will be shown. After that, all you need to do is select the destination of the installation and click on Continue.

  2. Xcode and iOS SDK on OS X Lion: To install Xcode and the SDK, a login to the Mac App Store is required. The downloaded files are basically an installer for Xcode and the SDK. When the download completes, run the Install Xcode application, and follow the installation instructions.

  3. Download and install Mono for Mac: The Mac version of Mono can be downloaded through the Mono Project's website: http://www.mono-project.com.

  4. Download and install MonoTouch: The latest evaluation version can be downloaded from http://ios.xamarin.com/DownloadTrial by providing an e-mail address.

  5. Download and install MonoDevelop 2.8+: Although creating iOS applications with MonoTouch does not require MonoDevelop, installing it will make developing much easier. It can be downloaded from http://monodevelop.com/Download.

How it works...

Now that we have everything ready, let's see what each component is needed for.

As stated in the introduction of this chapter, the iOS SDK contains three important components. The first component, Xcode, is Apple's IDE for developing applications for both iOS and Mac platforms. It is targeted on the Objective-C programming language, which is the main language to program in, with the iOS SDK. Since MonoTouch is an SDK for the C# language, one might wonder what we need Xcode for. Apart from providing various tools for debugging iOS applications, Xcode provides us with three important components that we need. The first one is a device information window, called Organizer, shown in the following screenshot, which is necessary to install the various certificates and provisioning profiles that are required for deploying our application on a device or distributing through the App Store. From within the Organizer, we can view debugging information of our applications, crash logs, and even take screenshots from the device! Of course, these are only a few of the many features Xcode provides, but they are outside of the scope of this book to discuss.

The second component is Interface Builder. This is the user interface designer, which was formerly a standalone application. Starting with Xcode 4.0, it is integrated into the IDE. Interface Builder provides all the necessary functionality to construct an application user interface. It is also quite different to what .NET developers have been accustomed to.

The third component is iOS Simulator. It is exactly what its name suggests: a device simulator, which we can use to run our applications on, without the need for an actual device. The important thing of iOS Simulator is that it has the option of simulating older iOS versions (if they are installed on the computer); both iPhone and iPad interfaces and device orientations. But, the simulator lacks some device features that are dependent on hardware, such as the compass or accelerometer. Applications using these features must be tested and debugged on an actual device.

Mono is an open source implementation of the .NET framework. It has been around for quite some time now and provides .NET developers the ability to program applications with .NET languages, while targeting all mainstream operating systems: Linux, Mac, and Windows. Both MonoTouch and MonoDevelop depend heavily on Mono, making it a necessary asset.

MonoDevelop is an open source IDE for developing applications with Mono (and the .NET framework on Windows). It provides code completion, database browser, GTK# designer, debuggers, and, in our case, the necessary components to develop iOS applications easily and effectively. It integrates with MonoTouch perfectly, classifying both as a complete iOS development environment.

MonoTouch is the SDK that allows .NET developers to develop applications for the iOS, using the C# programming language. There is a common misconception, mostly among new developers: since MonoTouch provides the ability to program with C#, one can install and use it on a Windows computer. This is totally wrong, since MonoTouch is wrapped around iOS SDK's libraries, which can only be installed on a Mac computer. Another misconception is that applications developed with MonoTouch being ".NET capable" require a virtual machine of some kind to be installed on the device to run, and they will run slower due to this virtual machine. This is also wrong, since MonoTouch's advanced compiler takes care of it by compiling our C# ".NET powered" code to native machine code. Also, a virtual machine being installed on a device is against Apple's guidelines.

There's more...

Applications developed with MonoTouch have the same chances of making it to the App Store as all other applications developed with the native Objective-C programming language! Meaning, if an application does not conform to Apple's strict policy about application acceptance, it will fail, whether it is written in either Objective-C or C#. The MonoTouch team has done a great job in creating an SDK that leaves the developer to only worry about the design and best practice of the code and nothing else. In April 2010, Apple made a modification on its application submission policy, which actually banned all applications from being submitted to the App Store that weren't created with the company's development tools. MonoTouch was one of them. Apart from the concern that emerged among developers who had already invested in MonoTouch, applications created with it were normally accepted on the App Store. In September 2010, Apple modified its policy and relaxed the matter, bringing relief to C# developers.

Useful links

The following is a list of the links that contain the tools and information for installing them:

Updates

MonoDevelop has a feature for checking for available updates. Whenever the program starts, it checks for updates of MonoDevelop itself, MonoTouch, and the Mono framework. It can be turned off, but it is not recommended, since it helps staying up-to-date with the latest versions. It can be found under MonoDevelop | Check for Updates.

See also

In this chapter:

  • Compiling

  • Debugging our application

Chapter 14, Deploying:

  • Debugging on other devices

  • Preparing our application for the App Store

 

Creating an iPhone project with MonoDevelop


In this task, we will discuss creating our first iPhone project with the MonoDevelop IDE.

Getting ready...

Now that we have all the pre-requisites installed, we will discuss how to create our first iPhone project with MonoDevelop.

Start MonoDevelop. It can be found in the Applications folder. MonoDevelop's default project location is the folder /Users/{yourusername}/Projects. If it does not exist on the hard disk, it will be created when we create our first project. If we want to change the folder, go to MonoDevelop | Preferences from the menu bar.

Select Load/Save in the pane on the left, enter the preferred location for the projects in the field Default Solution location, and click on OK.

How to do it...

  1. The first thing that is loaded when starting MonoDevelop is its Start page. Select File | New | Solution.... from the menu bar. A window will be shown that provides us with the available project options.

  2. In this window, on the pane on the left, select C# | MonoTouch | iPhone. The iPhone project templates will be presented on the middle pane.

  3. Select iPhone Single View Application. Finally, enter MyFirstiPhoneProject for Solution name and click on Forward. The following screenshot displays the New Solution window:

    That was it! You have just created your first iPhone project! You can build and run it. The iOS Simulator will start, with just a blank light-gray screen nevertheless.

Note

If the MonoTouch section on the left pane is not shown for some reason, it means that something went wrong with the installation of MonoTouch and/or MonoDevelop. Refer to the previous recipe for proper installation.

If the project templates in the middle are different than what is shown in this screenshot, it must be because you have a different version of MonoTouch and/or MonoDevelop than what was used for this book.

How it works...

Let's see what goes on behind the scenes.

When MonoDevelop creates a new iPhone, or better, iOS project, it creates a series of files. The solution structure is the same as if a .NET/Mono project was created, but with some extra files. The solution files can be viewed in the Solution pad on the left side of the MonoDevelop window. If the Solution pad is not visible, it can be activated by checking on View | Pads | Solution from the menu bar.

These files are the essential files that form an iPhone project:

MyFirstiPhoneProjectViewController.xib

This file is the file that contains the view of the application. XIB files are basically XML files with a specific structure that is readable from Interface Builder. They contain various information about the user interface, such as the type of controls it contains, their properties, Outlets, and so on.

Note

If MyFirstiPhoneProjectViewController.xib, or any other file with the .xib suffix is double-clicked, then MonoDevelop starts Xcode with the contents of the XIB file open in Interface Builder.

When we create a new interface with Interface Builder and save it, it is saved in the XIB format.

MyFirstiPhoneProjectViewController.cs

This is the file that implements the view's functionality. These are the contents of the file when it is created:

namespace MyFirstiPhoneProject{
public partial class MyFirstiPhoneProjectViewController : UIViewController{
  public MyFirstiPhoneProjectViewController (string nibName, NSBundle bundle) : base (nibName, bundle){}
  public override void DidReceiveMemoryWarning (){
    // Releases the view if it doesn't have a superview.
    base.DidReceiveMemoryWarning ();
    // Release any cached data, images, and so on that aren't in use.
  }
  public override void ViewDidLoad (){
    base.ViewDidLoad ();
    //any additional setup after loading the view, typically from a nib.
  }
  public override void ViewDidUnload (){
    base.ViewDidUnload ();
    // Release any retained subviews of the main view.
    // e.g. myOutlet = null;
  }
  public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation){
    // Return true for supported orientations
    return (toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown);
    }
  }
}

The code in this file contains the class that corresponds to the view that will be loaded, along with some default method overrides. These methods are the ones that we will be using more frequently when we create view controllers. A brief description of each method is listed as follows:

  • ViewDidLoad: This method is called when the view of the controller is loaded. This is the method we use to initialize any additional components.

  • ViewDidUnload: This method is called when the view is unloaded from memory.

  • DidReceiveMemoryWarning: This method is called when the application receives a memory warning. This method is responsible for unloading the view.

  • ShouldAutorotateToInterfaceOrientation: We implement this method when we want our application to support multiple orientations.

MyFirstiPhoneProjectViewController.designer.cs

This is the file that holds our main window's class information in C# code. MonoDevelop creates one .designer.cs file for every XIB that is added in a project. The file is auto-generated every time we save a change in our XIB through Interface Builder. This is being taken care of by MonoDevelop, so that the changes we make in our interface are reflected right away in our code. We must not make changes to this file directly, since when the corresponding XIB is saved with Interface Builder, they will be lost. Also, if nothing is saved through Interface Builder, if changes are made to it manually, it will most likely result in a compilation error.

These are the contents of the file when a new project is created:

namespace MyFirstiPhoneProject{
  [Register ("MyFirstiPhoneProjectViewController")]
  partial class MyFirstiPhoneProjectViewController{}
}

Just like any other .NET project, a namespace is created with the name of the solution:

namespace MyFirstiPhoneProject

This file contains the other partial declaration of our MyFirstiPhoneProjectViewController class. It is decorated with the RegisterAttribute.

The RegisterAttribute is used to expose classes to the underlying Objective-C runtime. The string parameter declares by what name our class will be exposed to the runtime. It can be whatever name we want it to be, but it is a good practice to always set it to our C# class' name. The attribute is used heavily in the internals of MonoTouch, since it is what binds all native NSObject classes with their C# counterparts.

Note

NSObject is a root class or base class. It is the equivalent of System.Object in the .NET world. The only difference between the two is that all .NET objects inherit from System.Object, but most, not all, Objective-C objects inherit from NSObject in Objective-C. The C# counterparts of all native objects that inherit from NSObject also inherit from its MonoTouch NSObject counterpart.

AppDelegate.cs

This file contains the class AppDelegate. The contents of the file are listed below:

using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace MyFirstiPhoneProject{
  // The UIApplicationDelegate for the application. This class is responsible for launching the 
  // User Interface of the application, as well as listening (and optionally responding) to application events from iOS.
  [Register ("AppDelegate")]
  public partial class AppDelegate : UIApplicationDelegate{
    // class-level declarations
    UIWindow window;
    MyFirstiPhoneProjectViewController viewController;
    // This method is invoked when the application has loaded and is ready to run. In this 
    // method, you should instantiate the window, load the UI into it, and then make the window visible.
    // You have 17 seconds to return from this method, or iOS will terminate your application.
    public override bool FinishedLaunching (UIApplication app, NSDictionary options){
      window = new UIWindow (UIScreen.MainScreen.Bounds);
      viewController = new MyFirstiPhoneProjectViewController ("MyFirstiPhoneProjectViewController", null);
      window.RootViewController = viewController;
      window.MakeKeyAndVisible ();
      return true;
    }
  }
}

The first part is familiar to .NET developers and consists of the appropriate using directives that import the required namespaces to use.

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

The first three using directives allow us to use the specific and familiar namespaces from the .NET/Mono world with MonoTouch!

Note

Although the functionality the three namespaces (System, System.Collections.Generic, System.Linq) provide is almost identical to their well-known .NET/Mono counterparts, they are included in assemblies specifically created for use with MonoTouch and shipped with it, of course. An assembly compiled with .NET or Mono cannot be directly used in a MonoTouch project.

The MonoTouch.Foundation namespace is a wrapper around the native Objective-C foundation framework, which contains classes that provide basic functionality. These objects' names share the same "NS" prefix that is found in the native foundation framework. Some examples are NSObject, NSString, NSValue, and so on. Apart from NS-prefixed objects, the MonoTouch.Foundation namespace contains all of the attributes that are used for binding to native objects, such as the RegisterAttribute that we saw earlier. The MonoTouch.UIKit namespace is a wrapper around the native Objective-C UIKit framework. As its name suggests, the namespace contains classes, delegates, and events that provide us with interface functionality. Except for two classes, DraggingEventArgs and ZoomingEventArgs, all the objects' names share the same "UI" prefix. It should be clear at this point that these two namespaces are essential for all MonoTouch applications, and their objects will be used quite frequently.

The class inherits from the UIApplicationDelegate class, qualifying it as our application's UIApplication Delegate object.

Note

The concept of a Delegate object in the Objective-C world is somewhat different than a delegate in C#. It will be explained in detail in Chapter 2, User Interface: Views.

The AppDelegate class contains two fields and one method:

UIWindow window;
MyFirstiPhoneProjectViewController viewController;
public override bool FinishedLaunching (UIApplication app, NSDictionary options) {

The UIWindow object defines the main window of our application, while the MyFirstiPhoneProjectViewController is the variable, which will hold the application's view controller.

Note

An iOS application typically has only one window, of type UIWindow. The concept of a UIWindow is somewhat different from a .NET System.Windows.Form. The UIWindow is the first control that is displayed when an application starts, and every subsequent views are hierarchically added below it.

The FinishedLaunching method, as its name suggests, is called when the application has completed its initialization process. This is the method where we must present the user interface to the user. The implementation of this method must be lightweight, since if it does not return in time from the moment it is called, iOS will terminate the application. This is for providing faster user interface loading times to the user by preventing developers from performing complex and long-running tasks upon initialization, such as connecting to a web service to receive data. The application parameter is the application's UIApplication object, which is also accessible through the static property UIApplication.SharedApplication . The options parameter may or may not contain information about the way the application was launched. We do not need it for now.

The default implementation of the FinishedLaunching method for this type of project is the following:

window = new UIWindow (UIScreen.MainScreen.Bounds);

The UIWindow object is initialized with the size of the screen.

viewController = new MyFirstiPhoneProjectViewController ("MyFirstiPhoneProjectViewController", null);
window.RootViewController = viewController;

The view controller is initialized and set as the window's root view controller.

window.MakeKeyAndVisible ();
return true;

The window is displayed on the screen with the window.MakeKeyAndVisible() call and the method returns. This method must be called inside the FinishedLaunching method, otherwise the application's user interface will not be presented as it should to the user. Last but not least, the return true line returns the method by marking its execution completion.

Main.cs

Inside the Main.cs file is where the runtime life-cycle of the program starts:

namespace MyFirstiPhoneProject{
  public class Application{
    // This is the main entry point of the application.
    static void Main (string[] args){
      // if you want to use a different Application Delegate class from "AppDelegate",
      // you can specify it here.
      UIApplication.Main (args, null, "AppDelegate");
    }
  }
}

Much like the following call in a .NET System.Windows.Forms application, the UIApplication.Main method starts the message loop, or run loop that is responsible for dispatching notifications to the application through the AppDelegate class, with event handlers that we can override.

// In a .NET application
Application.Run(new Form1());

Event handlers such as FinishedLaunching, ReceiveMemoryWarning , or DidEnterBackground are only some of these notifications. Apart from the notification dispatching mechanism, the UIApplication object holds a list of all UIWindow objects that exist; typically one. An iOS application must have one UIApplication object, or a class that inherits from it, and this object must have a corresponding UIApplicationDelegate object. This is the AppDelegate class implementation we saw earlier.

Info.plist

This file is basically the application's settings file. It has a simple structure of properties with values that define various settings for an iOS application, such as the orientations it supports, its icon, supported iOS versions, what devices it can be installed on, and so on. If we double-click on this file in MonoDevelop, it will open in the embedded editor, specifically designed for .plist files. This is what our file in a new project looks like:

The Info.plist is an XML file. Although we can edit the file manually in a text editor, for example, it is not recommended. The embedded editor is the best way of editing.

There's more...

MonoDevelop provides many different project templates for developing iOS applications. Here is a list that describes what each project template is for:

  • Empty project: It is an empty project without any views.

  • Utility application: It is a utility application is a special type of iOS application that provides one screen for functionality, and in many cases another one for configuration.

  • Master-detail application: This type of project creates a template that supports navigating through multiple screens. It contains two view controllers.

  • Single view application: This template type is the one we used in this recipe.

  • Tabbed application: It is a template that adds a tab bar controller that manages two view controllers in a tab-like interface.

  • OpenGL application: It is a template for creating OpenGL-powered applications or games.

These templates are available for the iPhone, the iPad, and Universal (both iPhone and iPad) projects. They are also available in Interface Builder's Storyboarding application design.

Note

Unless otherwise stated, all project templates referring to the iPhone are suitable for the iPod Touch as well.

List of MonoTouch assemblies

MonoTouch supported assemblies can be found in the following link: http://ios.xamarin.com/Documentation/Assemblies.

See also

In this chapter:

  • Creating the UI

  • Accessing the UI with outlets

In this book:

Chapter 2, User Interface: Views:

  • Adding and customizing views

 

Interface builder


Introduction to Apple's user interface designer.

How to do it...

If you have installed the iOS SDK, then you already have Xcode with Interface Builder installed on your computer.

  1. Go to MonoDevelop and open the project MyFirstiPhoneProject that we created earlier.

  2. In the Solution pad on the left, double-click on MyFirstiPhoneProjectViewController.xib. MonoDevelop starts Xcode with the file loaded in Interface Builder!

  3. On the right side of the toolbar, on the top of the Xcode window, select the appropriate editor and viewing options, as shown below:

    The following screenshot demonstrates what Interface Builder looks like with a XIB file open:

How it works...

Now that we have loaded Interface Builder with the view controller of our application, let's familiarize ourselves with it.

The user interface designer is directly connected to an Xcode project. When we add an object, Xcode automatically generates code to reflect the change we made. MonoDevelop takes care of this for us, as when we double-click on a XIB file, it automatically creates a temporary Xcode project so that we can make the changes we want in the user interface. Therefore, we have nothing more to do than just design the user interface for our application:

Interface Builder is divided into three areas. A brief description of each area is described below.

  1. Navigator area: In this area, we can see the files included in the Xcode project.

  2. Editor area: This area is where we design the user interface.

  3. Utility area: This area contains the Inspector and Library panes. The Inspector is where we configure each object, while the Library pane is where we find the objects.

The Editor area is divided into two sections. The one on the left is the Designer , while the one on the right is the Assistant editor. Inside the assistant editor, we see the underlying Objective-C source code file that corresponds to the selected item in the designer. Although we do not need to edit the Objective-C source, we will need the assistant editor later.

There's more...

We saw what a XIB file looks like in Interface Builder. But, there is more as far as these files are concerned. We mentioned earlier that XIB files are XML files with appropriate information readable by Interface Builder. The thing is that when a project is compiled, the compiler also compiles the XIB file, converting it to its binary equivalent: the NIB file. Both XIB and NIB files contain the exact same information. The only difference between them is that XIB files are in a human-readable form, while the NIB files are not. For example, when we compile the project we created, the MyFirstiPhoneProjectViewController.xib file will become MyFirstiPhoneProjectViewController.nib in the output folder. Apart from the binary conversion, the compiler also performs a compression on NIB files. So, NIB files will be significantly smaller in size than XIB files.

That's not all about XIB files. The way a developer manages the XIB files in a project is very important in an application's performance and stability. It is better to have many, smaller in size XIB files, instead of one or two large ones. This can be accomplished by dividing the user interface in many XIB files. It may seem a bit difficult, but as we'll see later in this book, it is actually very easy. We need many, smaller XIB files instead of few and large ones because of the way iOS manages its memory. When an application starts, iOS loads the NIB files as a whole in memory, and thereafter, all the objects in it are instantiated. So, it is a waste of memory to keep objects in NIB files that are not always going to be used. Also, remember that you are developing for a mobile device whose available resources are not a match against desktop computers', no matter what its capabilities are.

More info

You may have noticed that in the Attributes tab in the Inspector pane, there is a section called Simulated Metrics . Options under this section help us see directly in the designer what our interface looks like with the device's status bar, a toolbar, or a navigation bar. Although these options are saved in the XIB files, they have nothing to do with the actual application at runtime. For example, if we set the Status Bar option to None, it does not mean that our application will start without a status bar.

Note

Status Bar is the bar that is shown on the top portion of the device's screen, which displays certain information to the user, such as the current time, battery status, carrier name on the iPhone, and so on.

See also

In this chapter:

  • Creating the UI

  • Accessing the UI with outlets

  • Adding actions

In this book:

Chapter 2, User Interface:Views:

  • Adding and customizing views

Chapter 3: User Interface:View Controllers:

  • View controllers and views

 

Creating the UI


In this recipe, we will learn how to add and manage controls in the user interface.

Getting ready

Let's add a few controls in an interface. Start by creating a new iPhone Single View Application project in MonoDevelop. Name the project ButtonInput . When it opens, double-click on ButtonInputViewController.xib in the Solution pad to open it with Interface Builder.

How to do it...

Now that we have a new project and Interface Builder has opened the ButtonInputViewController.xib file, we'll add some controls to it.

Add a label

  1. Go to the Library pane and select Objects from the drop-down list, if it is not already selected. Select the Label object.

  2. Drag-and-drop the Label onto the gray space of the view in the designer, somewhere in the top half.

  3. Select and resize the Label from both the left and right side, so that it snaps to the dashed line that will show up when you reach close to the edges of the view.

  4. Again, with the Label selected, go to the Inspector pane, select the Attributes tab, and in the Layout section, click on the middle alignment button. Congratulations, you have just added a Label in your application's main view!

Add a button

We will perform similar steps to add a button in our interface.

  1. Again, in the Library pane, in the Objects section, select the Button object. It is next to the Label object.

  2. Drag-and-drop it onto the bottom half of the view. Align its center with the center of the Label we added earlier. A dashed line will show up, and the Button will snap to it when the centers of the two controls are almost aligned.

  3. Resize the Button to the same width of the Label. Since the Label has a transparent background and you cannot see how wide it is exactly, you will know when the Button is the same width when three dashed lines will show up while you are resizing it.

  4. Now, let's add some text to the Button. Select it and go to the Inspector pane. In the Attributes tab, in the Title field, enter Tap here please!.

  5. After adding the button, save the document through File | Save in the menu bar. The main view should now look like the following screenshot (shown resized here):

How it works...

As you can see, although some concepts of Interface Builder seem difficult, it is quite easy to use. It also provides a lot of feedback. When we drag objects, a green-circled cross appears on the cursor to declare that we can drop the object there. Also, when we resize a control, we see its dimensions next to it.

You can also resize and position the controls by modifying the values in the Size tab of the Inspector pane. Another useful feature in the Size tab is Autosizing. Autosizing provides layout options for the controls and can be very useful when we want our application to support different device orientations. You can select a control you want, and then click on the lines that are outside or inside of the square on the left in the Autosizing section. The image next to it animates to give you an impression of how the control will behave when the layout changes.

There's more...

Now, let's try running the application on the iOS Simulator. Back at MonoDevelop, select the project configuration at Debug | iPhoneSimulator if it is not already selected. No need to do anything else in the code for now; just click on the Run button. It is the third button on the right of the configuration combo box, with the double gear icon. When the compilation finishes, iOS Simulator will start automatically and will run the application we just created! You can even "tap" on the Button by clicking on it with the mouse and see it responding. Of course, our application does not have any other functionality right now.

Setting titles on buttons

Setting the title of a Button or a Label can easily be done just by double-clicking on it and typing the preferable title. Do it, and watch how Interface Builder behaves to show you what action is to be performed.

See also

In this chapter:

  • Compiling

  • Debugging our application

In this book:

Chapter 2, User Interface: Views:

  • Receiving user input with buttons

  • Using labels to display text

 

Accessing the UI with outlets


In this recipe, we will discuss the concept of Outlets and their usage with MonoTouch.

Getting ready

In the previous task, we learned how to add controls to form a basic interface for our application. In this task, we will discuss how to access and use these controls in our code. Launch MonoDevelop, and open the project ButtonInput that we created earlier. Open the project's ButtonInputViewController.xib in Interface Builder by double-clicking on it in the Solution pad.

How to do it...

  1. With the Assistant Editor open, Ctrl-drag from the label to the Objective-C source file, as displayed in the following screenshot:

    When you release the cursor, a context window will appear, similar to the one in the following screenshot:

  2. In the Name field of the context window, enter labelStatus, and click on Connect.

  3. Do the same for the button, and name it buttonTap . Save the Interface Builder document by selecting File | Save in the menu bar, or by pressing Option - S on the keyboard.

  4. Back in MonoDevelop, enter the following code in the ViewDidLoad method of the ButtonInputViewController class:

    // Create and hook a handler to our button's TouchUpInside event
    // through its outlet
    this.buttonTap.TouchUpInside += delegate(object sender, EventArgs e) {
      this.labelStatus.Text = "Button tapped!";
    };

    This code snippet adds a handler to the button's TouchUpInside event. This event is similar to the Clicked event of a Button control in System.Windows.Forms. It also displays the usage of an anonymous method, which just shows how MonoTouch provides C# features to .NET developers. That's it! Our application is now ready with functional controls.

  5. Compile and run it on the simulator. See the label changing its text when you tap on the button.

How it works...

The outlet mechanism is basically a way of connecting Interface Builder objects with the code. They are necessary, since it is the only way we can access user interface objects that we create with Interface Builder. This is how Interface Builder works, and it is not just a MonoTouch workaround. An outlet of an object provides a variable of this object, so that we will be able to use it in a project. MonoTouch makes a developer's life much easier, because when we create outlets in Interface Builder and connect them, MonoDevelop works in the background by auto-generating code regarding those outlets. This is what the ButtonInputViewController.designer.cs has added to provide us access to the controls we created:

[Outlet]
MonoTouch.UIKit.UILabel labelStatus { get; set; }
[Outlet]
MonoTouch.UIKit.UIButton buttonTap { get; set; }

These are the properties that provide us access to the controls. They are decorated with the OutletAttribute . You can see that the names of the properties are the exact same names we entered for our outlets. This is very important, since we only have to provide names once for the outlets and do not have to worry about repeating the same naming conventions in different parts of our code. Notice also that the types of the variables of the controls are exactly the same as the types of controls we dragged-and-dropped in our user interface. This information is stored in the XIB file, and MonoDevelop reads this information accordingly.

There's more...

To remove outlets, you first have to disconnect them. For example, to remove the buttonTap outlet, Ctrl - click on the button. In the panel that will appear, click on the small (x) next to the outlet. This will disconnect the outlet.

After that, delete the following code from the Objective-C source file:

@property (retain, nonatomic) IBOutlet UIButton *buttonTap;

When you save the document, the outlet will be removed from the MonoDevelop project.

Adding outlets through code

Another way of adding outlets is to create a property in your C# class and decorate it with the OutletAttribute:

[Outlet]
UIButton ButtonTap { get;	set; }

When you open the XIB file in Interface Builder, the outlet will have been added to the user interface. However, you would still have to connect it to the corresponding control. The easiest way to do this is to Ctrl - click on the control the outlet corresponds to and click-drag from New Referencing Outlet to the File's Owner object on the left of the designer area:

When you release the cursor, select the ButtonTap outlet from the small context menu that will appear.

Note

Note that it is MonoDevelop that monitors for changes made in Interface Builder and not the other way around. When making changes in the MonoDevelop project, make sure to always open the XIB file from inside MonoDevelop.

See also

In this chapter:

  • Interface builder

  • Creating the UI

  • Adding actions

In this book:

Chapter 2, User Interface: Views:

  • Adding and customizing views

 

Adding actions


In this recipe, we discuss the concept of Actions and their usage with MonoTouch.

Getting ready

In this task, we will discuss how to use actions with the controls of the user interface. Create a new iPhone Single View Application project in MonoDevelop, and name it ButtonInputAction . Open ButtonInputActionViewController.xib in Interface Builder, and add the same controls, outlets, and connections as the ones from project ButtonInput from the previous task. Do not add any code in the project for now.

How to do it...

Adding actions to interface objects is similar to adding outlets.

  1. In Interface Builder, Ctrl-drag from the button to the source code file. In the context window that will be shown, change the Connection field from Outlet to Action.

  2. Enter OnButtonTap in the Name field, and select Touch Up Inside in the Event field, if it is not already selected.

  3. Click on the Connect button, and save the document.

  4. In the ButtonInputActionViewController class, add the following method:

    partial void OnButtonTap(NSObject sender){
      this.labelStatus.Text = "Button tapped!";
    }
  5. The application is ready! Compile and run in the simulator.

  6. Tap on the button, and see the text in the label change, just like in the previous application we created.

How it works...

Actions in Objective-C are the equivalent of control events in C#. They are responsible for delivering notification signals of various objects. In this example, instead of hooking up a handler on the TouchUpInside event of the button, we have added an action for it. As you may already have noticed, the method we added to act as a handler for the action was declared as partial. That is because MonoDevelop already declared a partial method declaration for us. This is the code that was produced when we saved the document in Interface Builder:

[Action ("OnButtonTap:")]
partial void OnButtonTap (MonoTouch.Foundation.NSObject sender);

The partial declaration of the method is marked with the ActionAttribute . This is another attribute from the MonoTouch.Foundation namespace that allows us to expose methods as Objective-C actions. You see that the string parameter passed in the attribute is exactly the same as the action name we entered in Interface Builder, with an appended colon (:) to it.

Note

Colons in Objective-C indicate the presence of parameters. For example, doSomething is different than doSomething:. Their difference is that the first one does not accept any parameters, while the second accepts one parameter.

The colon at the end of the action name indicates that there is one parameter; in this case, the parameter MonoTouch.UIKit.NSObject sender. This is what our application looks like when we have tapped on the button in the simulator:

There's more...

The previous example was created just to show how to implement actions in MonoTouch projects. Replacing an event with an action is basically at the discretion of the developer.

See also

In this chapter:

  • Interface builder

  • Creating the UI

  • Accessing the UI with outlets

 

Compiling


In this recipe, we will discuss how to compile a project with MonoDevelop.

Getting ready

MonoDevelop provides many different options for compiling. In this task, we will discuss these options. We will be working with the project ButtonInput that we created earlier in this chapter.

How to do it...

  1. With the project loaded in MonoDevelop, go to Project | ButtonInput Options.

  2. In the window that appears, select iPhone Build from the Build section on the left pad. Select Debug as project configuration and iPhoneSimulator as a platform. In the Linker behavior field, select Link all assemblies from the combo box. In the SDK version field, select Default, if it is not already selected.

  3. Now, go to iPhone Application on the left pad.

  4. In the Summary tab, enter Button Input in the Application name field and 1.0 in the Version field. Select version 3.0 in the Deployment Target combo box. The iPhone Application options window is shown in the following screenshot:

  5. Click on the OK button, and compile the project by clicking on Build | Build All in the menu bar.

How it works...

We have set up some options for our project. Let's see what these options provide for compilation customization.

iPhone build options

The first option we set up regards the Linker. The Linker is a tool that was developed by the MonoTouch team and is provided in the SDK. Every time a MonoTouch project is compiled, the compiler does not only compile the project, but all the assemblies of the MonoTouch framework it needs, so that the final application will be able to run on the device (or the simulator). This actually means that every application comes with its own compiled version of the MonoTouch framework. Doing so means the final application bundle is quite large in size. This is where the Linker comes in. What it does is to strip down the assemblies of all the unused code so that the compiler will only compile what is needed and used by the application. This results in much smaller application bundles: a precious asset when it comes to mobile applications. Especially since Apple has a download limitation of 20 MB per file through the cellular network. The Linker options are the following:

  • Don't Link: Use this option when debugging on the simulator. The Linker is turned off, and all the assemblies are compiled as they are. This provides faster compilation times.

  • Link SDK assemblies only: Here, the Linker only strips down the MonoTouch Framework assemblies. The project assemblies remain intact. This option also effectively reduces the final size of the application.

  • Link all assemblies: Here, the Linker is activated on all assemblies. it reduces the size a bit more. Care needs to be taken when using this option, if Reflection or Serialization is used in the code. Types and methods that are used through Reflection in the code are transparent to the Linker. If a situation like this exists in the code, decorate these types or methods with the PreserveAttribute . This attribute basically informs the Linker to be left out of the stripping down process.

In the SDK version field, we set the iOS SDK version that will be used to compile the application. Setting it to Default automatically selects the highest SDK version installed on the system.

iPhone application options

In the iPhone Application window of the Build section in the project options, we have set up three options. The first option is the Application name . This is the name of the application bundle that will be displayed on the simulator, the device, and on the App Store. As we can see here, we can normally add spaces to the name. The second option, Version , defines the version of the application. It is what will be displayed as the application's version when it is finally distributed through the App Store. The third option, Deployment target , is the minimum iOS version the application can be installed on.

There's more...

There are two more option windows. These are iPhone Bundle Signing and iPhone IPA options. They will be discussed thoroughly in the recipes of Chapter 14, Deploying.

Linker usage

Note

When compiling for the simulator, turning the Linker on is not suggested. That is because the compiler is not compiling the MonoTouch assemblies in the iPhoneSimulator platform; hence they are being used directly. Turning the Linker on only causes compilation to take more time to complete. It has no effect in reducing the final application bundle size.

See also

In this book:

Chapter 14, Deploying:

  • Preparing our application for the App Store

 

Debugging our application


In this recipe, we will discuss information on debugging a MonoTouch application on the simulator.

Getting ready

MonoTouch, in combination with MonoDevelop, provides a debugger for debugging applications either on the simulator or on the device. In this task, we'll see how to use the debugger for debugging MonoTouch applications. Open MonoDevelop, and load the ButtonInput project. Make sure the debugger toolbar is activated by checking on View | Toolbars | Debugger in the menu bar. Also, set the project configuration to Debug | iPhoneSimulator.

How to do it...

  1. MonoDevelop supports breakpoints. To activate a breakpoint on a line, click on the space on the left of the line number to set it. Set a breakpoint on the following line in the Main.cs file:

    this.labelStatus.Text = "Button tapped!";

    This is what a breakpoint in MonoDevelop looks like:

  2. Compile and debug the project by clicking on the second button with the double gears icon from the left, or by clicking Run | Debug on the menu bar. MonoDevelop will display a message box with the message, Waiting for debugger to connect…. When the simulator is open and the app is loaded, watch the information that is provided in the Application Output pad. Tap on the app button. Execution will pause, and MonoDevelop will highlight the breakpoint in yellow. Move the mouse over the labelStatus variable in the breakpoint line. MonoDevelop will then display a window with all the evaluated variable's members:

  3. To stop debugging, click on the stop button on the toolbar, marked with a white (X) in a red circle.

How it works...

MonoTouch, in combination with MonoDevelop, uses a debugger called Soft Debugger . It is called this, because it depends on both the runtime and MonoDevelop combined to provide one unified debugging platform. When the debugging process starts, MonoDevelop begins listening for debugging information from the application. The same applies for debugging on both the simulator and the device. When the application executes, it starts sending information back to MonoDevelop, which then displays that information in the Application Output pad, which is automatically activated. A typical application output when debugging is the information on the assemblies that are loaded, the threads that begin execution, and the breakpoints, if any, that are available.

There's more...

The Console.WriteLine() method can also be used for debugging purposes. The debugger takes care of this and redirects the output of the method to MonoDevelop's Application Output pad.

Application performance when debugging

When compiling for debugging purposes, the compiler produces larger and slower code. That is because it generates extra code that is needed to provide the appropriate debugging information. That is why when debugging an application, the execution of the application is much slower than on simple running situations. Before producing a release copy of the application, remember to compile it with the Release | iPhone project configuration to avoid slow runtime execution.

Breakpoints in the FinishedLaunching method

One more reason not to have complicated code in the FinishedLaunching method is that in most cases, you will not be able to debug it. If you set a breakpoint in FinishedLaunching, application execution will pause, but iOS will terminate the application when the time limit is reached.

See also

In this book:

Chapter 14, Deploying:

  • Creating profiles

  • Debugging on other devices

About the Author

  • Dimitris Tavlikos

    Dimitris Tavlikos is a freelance software developer living in Greece. With over 10 years of professional experience as a programmer, he specializes in mobile development with clients all over the world. Dimitris has a passion for programming, and has recently been awarded the Xamarin MVP designation for his work. He has written a book on iOS development and various articles on his blog.

    Browse publications by this author
iOS Development using MonoTouch Cookbook
Unlock this book and the full library for $5 a month*
Start now