Code School

Ember.js Basics - What is Ember?

ember-basics-what-is-ember.png

According to the creators of the framework, Ember.js is “a framework for creating ambitious web applications”. What exactly do they mean? Also, with the many (, many, many) JavaScript frameworks that we have to choose from these days, why might I choose Ember? In this post, I’ll introduce Ember.js and some of the core concepts that backed its development. In future posts, I’ll dig in and show you how to build applications with the framework. For now, let’s look at what the framework is made of.

Guiding principles

Before looking at the details of any framework, it helps to understand the core concepts that drove the feature decisions in the first place. Perhaps the biggest factor in the creation of Ember was the belief that what makes the web so unique is the ability to bookmark and share URLs. The team felt that many JavaScript frameworks treated the URL as an afterthought (mostly by treating the concept of a router as an optional add-on). The Ember team also wanted to create an MVC framework that was closer in line with the desktop MVC framework mentality rather than taking a server-side MVC approach (like ASP.NET MVC or Ruby on Rails). So, Ember combines the productivity of a native UI framework while supporting shareable URLs. The following key concepts are what make up the framework from a high-level overview standpoint.

Core concepts

Naming conventions

Ember was written with convention over configuration in mind. This means that much of the framework relies on things being named consistently and in the manner that the framework expects. The naming conventions are summarized nicely here.

Templates

Templates are what describe the user interface in Ember.js. Ember templates are written using the Handlebars templating language which allows for expressions to be added to standard HTML markup within double curly braces: {{}}. Each template is backed by a model and supports databinding such that the template will auto-update when the model changes. The following features are supported in Ember’s Handlebars templates:

  • Plain HTML
  • Expressions - Allow model values to be substituted into the HTML. For instance, {{price}} would substitue the value of the price property on the model into the template where specified
  • Outlets - An outlet (specified by {{outlet}}) is a placeholder for another template. As the user moves around the application, different templates can be loaded into the outlet by the router.
  • Components - Custom HTML elements (technically, custom Handlebars helpers) that help clean up repetitive templates by enabling the creation of reusable controls

Example template:

Router

The router in Ember is what powers the shareable URLs that are so important to web applications. The router translates the URL of a request into a series of templates. For instance, when I visit /coffee within the application, Ember’s router will translate this to the CoffeeRoute which will set up the appropriate template backed by the appropriate model for that request. As the templates or models being shown to the user change, Ember’s router will automatically keep the URL in the browser up to date. This means that the user can share the URL at any point in the application lifecycle. Whenever someone clicks on this shared URL, they will see the same thing that the original user saw.

Example router:

Models

A model object is used to store persistent state within an Ember application. These model objects are what back the templates and provide data to be displayed within the HTML. Many applications will load these models through a REST API using Ember Data which will store the data in a server database, but Ember doesn’t limit you to just this choice. There are many adapters for Ember Data that allow you to choose the backend that works best for your project. You can even roll your own syncing using the Basic Adapter.

Example model:

Controllers

The controller is technically where the templates get their data from. Though optional, a controller will be created by Ember if not directly declared for a route. The controller “decorates” the model object. Properties specified on the controller can be accessed by a template as if they were declared on the model. Methods can be created within the controller that can be called using Handlebars helpers in the template. This enables things like button actions. In general, properties that do not need to be synced to the backend server but are necessary for template logic should be created in the controller. Ember supports the creation of ObjectControllers, which manages a single model object, and ArrayControllers which manage a list of model objects.

Example controller:

Components

Components allow for the creation of reusable controls. The interface for the component is defined using Handlebars templates. The component also has a JavaScript class that is used to store state and handle user interaction. Components are placed into a template using a Handlebars helper with a name based off of the name of the component.

Example component:

Summary

Ember.js is a relatively young but growing framework. Though in the past it suffered from a lack of documentation and a difficult learning curve, that situation has improved dramatically. The Ember guides are very well-written and will help you get started with the framework in no time. I will also be posting more on how to develop with this framework over the coming weeks.

Contact

If you want to comment or reach out to me, the best place to do that is on Twitter @brentschooley. You can also contact me through the contact form at brentschooley.com.

Plantronics Voyager PRO UC v2 Review

Over the past few weeks, I've been trying out a Bluetooth headset from Plantronics called the Voyager PRO UC v2.  Plantronics bills this as a next-generation device which offers Smart Sensor technology, outstanding audio quality, and superior call management.  Another interesting feature of the device is the integration with Plantronics' Spokes SDK which allows you to access headset events and contextual usage data from within your applications.

The device

Just about anyone who has shopped around for Bluetooth headsets will be familiar with the design of the Voyager PRO UC.  It features an over-the-ear design with a rotating boom microphone that easily accommodates wearing on the right or left ear.  Volume buttons are conveniently located at the top of the device while the power button is on the back at the bottom.  Inside the box were 3 different sizes of earpieces and a leather carrying case.  The headset charges using a standard micro-USB port located on the bottom of the unit.  One other important thing included in the box is the small USB adapter that enables the headset to connect with your computer.  The adapter comes pre-paired with the headset so you don't need to fumble around with the Bluetooth settings on your computer to get up and running.  Once connected to the USB adapter, the headset will be able to relay information to the computer that can be leveraged using the Spokes SDK.

Pictures:

Audio quality

All of the technological advances in the world won't mean a thing for a Bluetooth headset if the audio quality isn't great.  Thankfully, the Voyager PRO UC v2 excels in this area.  Both incoming and outgoing audio from this device are stellar.  One person I called even said they had no idea I was using a headset.  Noise cancellation (referred to as AudioIQ2 noise canceling technology in Plantronics' literature) seems to be working great on this device as I tried a few calls in somewhat noisy environments and the person on the other end didn't complain about background noise.  The "WindSmart technology" is something I was very eager to try out since most headsets have major problems with wind.  I tried the Voyager PRO UC v2 on a few very windy days and again, the headset held up to the challenge.  It is definitely one of the best headsets I've tried in terms of audio quality.

Technology

The technological aspects of this device are where it really shines.  The Voyager PRO UC v2 has Smart Sensor™ technology that enables the headset to transmit contextual information to the computer.   While communicating with the USB adapter, the headset will report a variety of information such as proximity, battery level, and whether or not the device is being worn.  Since the device is able to detect whether it is on ear or not, it is capable of automatically transferring calls from your phone to the headset without needing to press a button.  When streaming audio over A2DP, removing the headset will smartly pause the music.  This all works out of the box without any need for additional programming.

However, the combination of sensors providing contextual data and the various amount of information available through the APIs in the Spokes SDK offers up a variety of potential application scenarios.  The information accessible through the Spokes SDK includes: wearing state, proximity, caller ID and call management, unique ID of the device, and device usage stats.   You can also send commands to the device using the Spokes SDK. The different types of applications that can potentially be developed using this SDK are described nicely in this post on the Plantronics' blogs.  A white paper for the Spokes SDK describes the benefits applications can gain by leveraging the contextual data provided by these smart devices.

I tried the SDK out for myself.  To get started, I needed to obtain the Spokes SDK from the Plantronics Developer Connection (PDC) which can be found at developer.plantronics.com.  The PDC contains a variety of resources including documentation, forums, blogs, as well as many samples.  A great place to get started once you have installed the Spokes SDK is the DevZone where you'll find a curated list of samples and documentation.

Since I've been mostly living in a Windows 8 world lately, I found the inclusion of a REST API accessible through Javascript to be very appealing.  I started with the "Hello Plantronics World!" example that I found on the developer portal.  This allows you to connect to your device and view event logs as well as send a few basic commands.  It looks like this:

Screenshot 12:17:12 5:00 PM.jpeg

My next challenge was getting the spokes.js file to work within the confines of WinJS.  After a bit of wrestling with jQuery and WinJS interaction, I was able to get some parts of the API to work.  I was not able to get event polling to work, but this is not a problem with the Spokes REST API, it's a problem in my port of spokes.js.  Given a bit more time, I'm certain I'll be able to get things fully functioning in WinJS.  For now, here's a screenshot to prove you can talk to the device in a Windows Store application!:

screenshot_12172012_170201.png

Summary

Overall, this is a great device.  Even without the SDK and smart sensors it is one of the best headsets I have tried.  The audio quality, noise cancellation, and wind protection are top-notch for this type of device.  Add to this all of the tech smarts and you have a device that is very unique in the field.  Plantronics has also recently released the Voyager Legend UC which promises to provide even better quality and more contextual information out of the box.

I would highly recommend developers check out these smart devices and the Spokes SDK.  The APIs exposed by the SDK will allow you to develop some really cool applications that take advantage of the data provided by the sensors in the headset.

Southwest Florida .NET Code Camp 2012 Recap

IG-CodeCamp-SWFL

This past weekend I had the wonderful opportunity to attend and speak at the Southwest Florida .NET Code Camp 2012 in sunny Naples, FL.  It was a great event with over 80 attendees.  I was there as both a speaker and a sponsor and I also brought my father and brother to the event.  I'd like to thank John Dunagan again for putting on a fantastic event.  I presented 3 sessions at the code camp and I wanted to take some time to provide some additional resources for those that attended the sessions.

HTML5 and jQuery Fundamentals

Originally, my boss Jason Beres was supposed to be attending this event but he needed to attend TechEd Australia instead.  Since he was planning on presenting a session on HTML5 and jQuery I figured I would take that session slot and give it a try.  I'm still learning HTML5 and jQuery so I'm certainly not an expert.  However, I took Jason's content and made some slides of my own and gave it a shot as a high-level overview.  I thought the session went well and the attendees seemed engaged and appreciative.  I promised I'd share my slides and Jason's original material (including some content I didn't get to talk about).  Here are the links:

Windows 8 Design Fundamentals

The material in this session hasn't changed since previous events I've given the talk at.  You can find more details on those here and here.  However, one thing that is new is that I'm writing a book on the subject.  Please pre-order Designing for Windows 8 today and you'll get it when it's done in December!

designwin8

designwin8

Create iOS apps using C# with Monotouch

I added this session for a bit of fun after I noticed that there weren't any sessions at the code camp dealing with MonoTouch or Mono for Android.  I think these are very important technologies and I didn't want to let them go unrepresented.  The session was at the end of the day so I kept it lighthearted with no slides and a few "Hello World"-style demos.  I discussed the origins of MonoTouch and Xamarin and a little bit of the turmoil those have been through in the past.  Thankfully, those things are in the past and we can safely use MonoTouch to build iOS apps without worrying about Apple interjection.  I showed how to use MonoDevelop in tandem with Xcode to create a very basic application.  I then showed how to build the same application using just Xcode with Objective-C.

I didn't have slides for this session but I do have one follow-up piece of information from the session.  I mentioned a service that allows you to run MonoTouch in the cloud in case you don't feel like buying a Mac.  That service is called MacInCloud and it might be a good option for you.

Summary

I had a great time at this event.  I would highly recommend it to anyone next year.  The location is fantastic, the facilities were very accommodating, and the people were very friendly.  If you're looking for an excuse to take a trip to Florida, this would be a good one.

Windows 8 Style Apps?

Windows 8 Style Apps?

While watching the live video from the Microsoft Office Preview event, me and my colleagues all had the same reaction (almost simultaneously in different locations) and we posted it to Twitter at roughly the same time:

Microsoft all made us scratch our heads because I think we've all gotten used to the term "Metro style apps".  Originally this term seemed awkward (especially the use of the work 'style' in it), but we all got used to it.  We wrote posts about it.  We gave presentations about it.  The term maybe even grew on us a bit.  So now Microsoft seems like they're going to replace it with "Windows 8 Style Applications"?  Immediate reaction from my colleague @brianlagunas:

I think we've had some time to digest this (pun intended) and maybe it's time to revisit the term and whether or not Microsoft meant this as a replacement term because I have my doubts.  Here's my theory:

There is a lot of confusion in the software world regarding the Metro design language.  For starters, when it is applied to an immersive, full-screen Windows 8 application that is launched from the Start screen, we have been calling that a "Metro style app".  But what do you call a desktop application running on Windows 8 that has been styled using the Metro design language in an attempt to fit in with the system even though it is running in the classic desktop?  It is still technically "Metro style".  Is it possible that Microsoft was just referring to this scenario?  That's my theory at the moment but I'd really like some clarification from Microsoft on this soon.  It's hard to communicate these things to customers when there are competing terms floating around.

What are your thoughts?  I'd really be interested in hearing them, so comment on this post or find me on Twitter @brentschooley.

Introduction to MVC in Xamarin.iOS - Part 1: The basics

Model-View-Controller (MVC) Pattern

Model-View-Controller, or MVC, is a design pattern that is often used in creating mobile applications. In an MVC application, the major building blocks of the application are either model objects, view objects, or controller objects.

Definition of MVC objects

Model objects are used to represent the data in your application. If designed appropriately, model objects can be reused in multiple projects. This is especially important in cross-platform scenarios. For model objects to be reusable,  they should not know details about how your views and controllers operate.

View objects represent things on screen. For instance, a button or a table view would be view objects.  Primary responsibilities for view objects include drawing themselves on screen and responding to events.  View objects should not have direct access to the model.

Controller objects are used to coordinate the models and the views to create the application.  Controllers can fetch data from the model and hook it up to the corresponding views in the application. When data needs updated or saved, the controller can help facilitate this task by leveraging the model.  Controllers are also responsible for handling application flow, e.g.  navigating between screens.

MVC in Xamarin.iOS

Model objects can range in complexity from simple arrays all the way up to complex custom object hierarchies.  The data they represent can either be static data contained in the project or dynamic data fetched from a database or the Internet.

View objects in iOS derive from UIView or any of its subclasses, such as UIButton or UISlider.  Views can either be standard controls from UIKit or custom view classes derived from UIView.

Controller objects in iOS are represented by subclasses of UIViewController. In an iPhone application, each view controller represents one screen’s worth of data. In an iPad application, a view controller might represent a whole screen or it may just represent a functional unit of the screen such as a controller for a list displayed on the screen. For this tutorial, we will focus on the iPhone scenario since iPad view controller hierarchies can get complicated. Each view controller has a View property that is used to manage its view hierarchy. Methods defined in UIViewController can be overridden in view controller subclasses to participate in what Apple refers to as the View Controller Lifecycle. For instance, a view controller can override LoadView to create and load its view object and override ViewDidLoad to customize the view after it has loaded.

Tutorial: Implementing a basic Model-View-Controller application

In this tutorial, we will create a single screen iPhone application that displays the name and price for a grocery store product. The model object will be a simple C# object called Product with properties for name and price. The view object will be a custom view object called ProductView which will derive from UIView and contain UILabels to display the name and price for a product and a button to raise the price 10 cents. Even though most of the examples you will find on the Internet will use Interface Builder XIBs to create the user interface, the first version of this application will layout the controls in code to show how this is done programmatically. Future tutorials will cover how to create the views in the interface designer in Xcode. The controller will be a subclass of UIViewController which will be called ProductViewController.

Setting up the project

Empty Project

Empty Project

Start by creating an empty iPhone project by selecting File->New->Solution… in Xamarin Studio and then selecting C#->iOS->iPhone->Empty Project in the New Solution window. Name your project “MVCTutorialOne” as shown in the screenshot and click “OK”.

Folders Added

Folders Added

Right-click on the MVCTutorialOne project node in the Solution pane and select Add->New Folder to create a new folder. Name it “Models”. Then create two more folders named “Views” and “Controllers”. These folders are not required for the application to work, but they help to reinforce which files in the project are supporting which roles in the MVC pattern we are following. When you have finished this step, your project should look like the following screenshot:

Creating the Product model

Right-click on the Models folder and select Add->New File… Select “Empty Class” from the “General” category. Name the class “Product” and click “New”. Add two public properties to the class, a Name property of type string and a Price property of type double. We don’t need the default constructor, so you can delete it if you want. Your model class should look like (or similar) to this:

using System; 
namespace MVCTutorialOne { 
	public class Product { 
		public string Name { get; set; } 
		public double Price { get; set; } 
	} 
}

Very simple object to represent a basic product. 

Creating the Product view

Right-click on the Views folder and select Add->New File… Select “Empty Class” from the “General” category. Name the file “ProductView” and click “New”. There are options in the “iOS” category for creating views with and without view controllers but they all create Interface Builder files for creating the user interface. Since we are creating the view manually in code, we want to start with an empty file.

The following steps are based on the Checklist for Implementing a Custom View which is found in the View Programming Guide for iOS.

Step One: Add using statements for System.Drawing and MonoTouch.UIKit to the top of your ProductView class:

using System.Drawing; 
using MonoTouch.UIKit;

Step Two: Set the superclass for ProductView to UIView.

public class ProductView : UIView { 
	// ... 
}

Step Three: According to the checklist, since we are planning to create the view programmatically we need to implement the version of the constructor that takes a frame as the parameter.

// Initialization 
public ProductView (RectangleF frame): base(frame) { 
	// ... 
}

Step Four: The next step in the checklist that pertains to our view is setting the AutoresizingMask, which we’ll add to the constructor. We’ll also set the background color of the view to white.

// Set the background color for the view 
this.BackgroundColor = UIColor.White; 

// Set the AutoresizingMask to anchor the view to the top left but 
// allow height and width to grow 
this.AutoresizingMask = (UIViewAutoresizing.FlexibleRightMargin | UIViewAutoresizing.FlexibleBottomMargin | UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth);

Step Five: Next up in the custom view checklist is the creation and initialization of the subviews the custom view will manage. In our view we will have 3 subviews: the name label, the price label, and the increment button. Create public properties for the three subviews.

// Subview properties 
public UILabel NameLabel { get; set; } 
public UILabel PriceLabel { get; set; } 
public UIButton IncrementButton { get; set; }

To create the name label and add it to the ProductView, add the following code to the ProductView constructor:

this.NameLabel = new UILabel () { 
	Frame = new RectangleF (20, 20, 280, 20), 
	AutoresizingMask = (UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleRightMargin) 
}; 

this.AddSubview (this.NameLabel);

This code sets the location of the name label to be 20px from the top and left of ProductView. It also sets the width to 280px and the height to 20px. All of these are set on the Frame property. The AutoresizingMask is set such that the width will be flexible while remaining anchored to the left side. Add similar code to the constructor to set up the price label (the only difference is the y-coordinate in the Frame):

this.PriceLabel = new UILabel () { 
	Frame = new RectangleF (20, 49, 280, 20), 
	AutoresizingMask = (UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleRightMargin) 
}; 

this.AddSubview (this.PriceLabel);

Now we will add code to create the increment button subview.

// Create a default rounded rectangle button 
this.IncrementButton = UIButton.FromType (UIButtonType.RoundedRect);

// Set the frame 
this.IncrementButton.Frame = new RectangleF (20, 78, 280, 37); 

// Adjustible width with left anchor this.IncrementButton.AutoresizingMask = (UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleRightMargin); 

// Set the title to "Increment Price $0.10" 
this.IncrementButton.SetTitle (String.Format ("Increment Price {0:C}", 0.1), UIControlState.Normal); 

this.AddSubview (this.IncrementButton);

Since our subviews don’t require and custom layout and we aren’t handling any touch-based gestures in the ProductView class, we have satisfied the custom view checklist. The final ProductView class should look like this:

using System; 
using System.Drawing; 
using MonoTouch.UIKit; 
namespace MVCTutorialOne { 
	public class ProductView : UIView { 
		// Subview properties 
		public UILabel NameLabel { get; set; } 
		public UILabel PriceLabel { get; set; } 
		public UIButton IncrementButton { get; set; } 

		// Initialization 
		public ProductView (RectangleF frame): base(frame) { 
			// Set the background color for the view
			this.BackgroundColor = UIColor.White; 
			// Set the AutoresizingMask to anchor the view to the top left but 
			this.AutoresizingMask = (UIViewAutoresizing.FlexibleRightMargin | UIViewAutoresizing.FlexibleBottomMargin | UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth); 
			this.NameLabel = new UILabel () { 
				Frame = new RectangleF (20, 20, 280, 20),
				AutoresizingMask = (UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleRightMargin) 
			}; 
			
			this.AddSubview (this.NameLabel); 
			
			this.PriceLabel = new UILabel () { 
				Frame = new RectangleF (20, 49, 280, 20),
				AutoresizingMask = (UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleRightMargin) 
			}; 

			this.AddSubview (this.PriceLabel); 

			this.IncrementButton = UIButton.FromType (UIButtonType.RoundedRect); 
			this.IncrementButton.Frame = new RectangleF (20, 78, 280, 37); 
			this.IncrementButton.AutoresizingMask = (UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleRightMargin); 
			this.IncrementButton.SetTitle (String.Format ("Increment Price {0:C}", 0.1), UIControlState.Normal); 
			
			this.AddSubview (this.IncrementButton); 
		} 
	} 
}

Creating the Product view controller

Right-click on the Controllers folder and select Add->New File… Select “Empty Class” from the “General” category. Name the file “ProductViewController” and click “New”. There are options in the “MonoTouch” category for creating ViewControllers, but this templated approach will add a lot of methods we won’t need and might make it difficult to understand what is going on. It’s better to build the view controller with only the parts we need.

Step One: Add using statements for System.Drawing and MonoTouch.UIKit to the top of your ProductView class.

using System.Drawing; 
using MonoTouch.UIKit;

Step Two: Set the superclass for ProductViewController to UIViewController.

public class ProductViewController : UIViewController { 
	// ... 
}

Step Three: Since our controller will be coordinating a product model and the product view, we will create fields to manage these objects.

// Model 
private Product _product; 

// View 
private ProductView _productView;

Step Four: In the constructor for the view controller, initialize the _product model and set some values for the product. (Note: Since the model object is small and we are using static data, we will create the product here in the constructor for this tutorial. In a situation where we need to fetch more substantial data we’ll need to asynchronously fetch the data at a different point in the process. This will be covered in a later tutorial.)

public ProductViewController () { 
	_product = new Product () { 
		Name = "Strawberry Fizzy Pop", 
		Price = 1.59 }; 
}

Step Five: We are going to use a few methods that update the _productView’s labels based on the _product model’s values. These will be needed later in the view controller creation process.

public void UpdateNameLabel () { 
	_productView.NameLabel.Text = string.Format ("Product Name: {0}", _product.Name); 
} 

public void UpdatePriceLabel () { 
	// Format as currency 
	_productView.PriceLabel.Text = string.Format ("Price: {0:C}", _product.Price); 
}

Step Six: Next, we need to override the LoadView method. This method is used to programmatically load the view for the view controller when an Interface Builder XIB is not being used to create the view. We didn’t create or refer to the view in the view controller’s constructor because iOS lazy loads the view controller’s view. LoadView will only be called if the ProductViewController.View property is accessed and is null at the time of access.

public override void LoadView () { 
	// Set the frame for the product view to fill the screen taking into 
	// account the 20px tall status bar. 
	_productView = new ProductView (new RectangleF (0, 20, 320, 460)); 
	
	this.View = _productView; 
}

Step Seven: Once the view has loaded, there is a method that will get called on the view controller called ViewDidLoad. We can override this method to provide code to customize the newly loaded view. All of the view hierarchy for the view controller will have been created by this point so it is safe to update these objects. We first call base.ViewDidLoad() to allow for superclass initialization. Then, we call the UpdateNameLabel() and UpdatePriceLabel() methods to set their text based on the _product model.

if (_product != null) { 
	UpdateNameLabel (); 
	UpdatePriceLabel (); 
}

In the MVC object introduction I mentioned that one of the view responsibilities was responding to events. ProductView’s IncrementButton object can respond to a variety of touch related events. The one we are interested in is the TouchUpInside event which will fire when a user presses and releases the button. We will set up an event handler for this event in the ViewDidLoad method the first updates the _product model’s Price property and then calls UpdatePriceLabel() to refresh the price label based on the new model value. (Note: I am using lambda syntax but you can use a delegate as you would with any other event.) This is a very good example of the type of coordination work a controller performs in the MVC pattern.

_productView.IncrementButton.TouchUpInside += (s,e) => { 
	_product.Price += 0.1; 
	UpdatePriceLabel (); 
};

Step Eight: There is one last method we will override in our view controller for this tutorial. This method is the ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation) method. By overriding this method we can define which orientations we wish to support in the application. For this tutorial, we will support all orientations except PortraitUpsideDown.

public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation) { 
	// Support all but the "upside down iPhone" orientations 
	return toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown; 
}

At this point, the view controller code is complete. All iOS applications have a single window which can contain a view hierarchy. To add our ProductViewController’s view to the window, we’ll need tocreate an instance of ProductViewController in the AppDelegate’s FinishedLaunching method and add its view to the application window’s subviews.

var pvc = new ProductViewController (); 
window.AddSubview (pvc.View);

Once this step is completed, our app is done. Run the application and try pressing the Increment button to see the price change.

 

FinishedApp

FinishedApp

Get the code

If you're having trouble with recreating the tutorial, you can find the original source on GitHub at https://github.com/brentschooley/monotouch-tutorials

Conclusion

This article and corresponding tutorial introduced the Model-View-Controller pattern that is used in Xamarin.iOS. We created a simple model object, a custom view to represent it, and a controller object to make them work together within the iOS framework. The next tutorial will cover creating the view objects as Interface Builder XIB files and hooking them up to a view controller. A follow-up to that tutorial will cover how to load a data model from a SQLite database asynchronously and display it in a table view.