Using Monotouch with the .Net library for the Google Data API

Update: With the recent release of Monotouch 1.1 and the associated update to MonoDevelop, the Mono for iPhone runtime option is no longer directly available. Instead, you now create a “Monotouch Library Project” to have the runtime set to Mono for iPhone. For an existing library project, like the ones in this post, you can edit the project file in a text editor and add the appropriate ProjectTypeGuid element (create a new Monotouch Library Project and open it in a text editor to get the correct value to put in your csproj files).

One of the interesting things about Monotouch is that it allows you to incorporate an existing c# library in an iphone application. In this post I’ll show you how to adapt Google’s open source .Net client library to access the Google calendar service using Monotouch. I’m using version 1.4.0.2 of the Google Data API which you download from the following url:

http://google-gdata.googlecode.com/files/libgoogle-data-mono-1.4.0.2.tar.gz

First we’ll create a new Monotouch application named gCal using the iPhone Monotouch Project solution template in MonoDevelop. In MonoDevelop right-click (or ctrl-click) the gCal solution and select Add->Add Exisiting Project. Navigate to the location where you unzipped the libgoogle-data-mono-1.4.0.2 directory and then to the src subdirectory. The projects we’ll be using are Access Control, Calendar, Common Data Extensions and Core Client, the projects for which are located under src in gacl, gcalendar, extensions and core respectively. So to add Access Control, navigate to /src/gacl in the “Add to Solution” window and select Access Control.csproj. Repeat the process for the other 3 projects. You’ll need to change the build target for each project to be Mono for iPhone. Right-click on the Access Control project and select Options->Build->General. In the runtime version dropdown select Mono for iPhone:

Repeat this for the Calendar, Common Data Extensions and Core Client projects.

The Google library has a dependency on System.Web for the class HttpUtility. Fortunately this is implemented in the mono source code proper. You can fetch it here: http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/System.Web/System.Web/HttpUtility.cs (Thanks to Miguel for mentioning this on the monotouch list). Add a new C# library project named System.Web to the solution and add the HttpUtility.cs file to it. I commented out the AspNetHostingPermissionAttribute and the using System.Web.Util statement in the HttpUtility class as they weren’t needed in this project. Change the build target on the System.Web project to Mono for iPhone as before. One last thing to do is in the Core Client project tracing.cs file, comment out any calls to the Trace class, such as Trace.WriteLine, Trace.Flush and Trace.Assert (you could implement them as well if you wish, but it isn’t really necessary for demonstration). Build the solution to make sure everything is added correctly.

Now you are ready to use the library from monotouch. Let’s add a simple table view to display your list of google calendar events. Right-click on the gCal project->Edit References and add a project reference to all the other projects in the solution:

Next double-click on the MainWindow.xib to open interface builder. Add a UITableViewController to the xib file and name the class CalTVC. Add an outlet to the UIApplicationDelegate named calTVC and connect the outlet to the CalTVC UITableViewController that you previously added. Save and close interface builder.

Now we need to add the code for the UITableViewController. Add a new class to gCal project named CalTVC.cs. Add the following code to the class (see the monocatalog example for the sample code this is based upon):

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

namespace gCal
{
 public partial class CalTVC : UITableViewController
 {
 static NSString kCellIdentifier = new NSString ("CellIdentifier");

 public CalendarFacade Calendar { get; set; }

 public CalTVC (IntPtr p) : base(p)
 {
 }

 class DataSource : UITableViewDataSource
 {
 CalTVC _calController;

 public DataSource (CalTVC calController)
 {
 _calController = calController;
 }

 public override int RowsInSection (UITableView tableView, int section)
 {
 return _calController.Calendar.Events.Count;
 }

 public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
 {
 var cell = tableView.DequeueReusableCell (kCellIdentifier);

 if (cell == null)
 {
 cell = new UITableViewCell (UITableViewCellStyle.Default, kCellIdentifier);
 }

 cell.TextLabel.Text = _calController.Calendar.Events[indexPath.Row];

 return cell;
 }
 }

 public override void ViewDidLoad ()
 {
 base.ViewDidLoad();
 string googleUsername = "enter your google username here";
 string googlePassword = "enter your google password here";

 Calendar = new CalendarFacade (googleUsername, googlePassword);

 TableView.DataSource = new DataSource (this);
 }

 }
}

Notice the use of a class called CalendarFacade. This is the class that makes use of the Google library. The Authentication call to Google Data Service happens on https and mono doesn’t have any trusted root by default. For this demo, we’ll just bypass this to make things work by implementing ICertificatePolicy and returning true from CheckValidationResult, but you should consider this more carefully in an app you are going to release. See http://www.mono-project.com/UsingTrustedRootsRespectfully and http://www.mono-project.com/FAQ:_Security for more details.

using System;
using Google.GData.Calendar;
using Google.GData.AccessControl;
using Google.GData.Client;
using Google.GData.Extensions;
using System.Linq;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using System.Net;

namespace gCal
{
 public class CalendarFacade
 {
 CalendarService _csvc;
 string _username;
 string _pwd;
 List _eventTitles;

 public CalendarFacade (string username, string pwd)
 {
 _username = username;
 _pwd = pwd;

 ServicePointManager.CertificatePolicy = new Trustee ();

 _csvc = new CalendarService ("mycompany-myapp-1");
 _csvc.setUserCredentials (_username, _pwd);
 }

 class Trustee : ICertificatePolicy
 {
 public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
 {
 return true;
 }
 }

 public List Events
 {
 get
 {
 if (_eventTitles == null)
 {
 string calUri = "http://www.google.com/calendar/feeds/default/private/full";

 EventQuery calQuery = new EventQuery (calUri);

 EventFeed calEvents = (EventFeed)_csvc.Query (calQuery);

 _eventTitles = calEvents.Entries.Select (calEventEntry => calEventEntry.Title.Text).ToList ();
 }

 return _eventTitles;
 }
 }
 }
}

The CalendarFacade creates a CalendarService instance using the passed in credentials. After this happens, we’re free to call into the library as needed. This example simply returns all the calendar entries and returns the event title for each entry to be loaded in the table view we previously created.

Here’s an screenshot of the app running:

9 thoughts on “Using Monotouch with the .Net library for the Google Data API

  1. Pingback: MonoTouch.Info
  2. Hi Mike,

    I’m trying to follow your example here but I think a lot has changed with Monotouch in the last 6 odd months 🙂

    I can’t change the runtime of each of the projects that I add to Mono for Iphone as it is not an option.

    When editing the references in the gCal project, I go to the Projects tab and the other projects are there but are greyed out and I have no way to add them to the selected References window below.

    Can you help me figure this out please?

    Thanks

  3. I tried to add: {E613433A2-FE9C-494F-B74E-F63BCB86FEA6};{FAE04EC0-301F-14D3-BF4B-00564F79EFBC} to my project file but then it would not open with MonoDevelop, it says it’s an unknown project type. Any other thought?

    Thanks,
    Rick

  4. Reverted to Google version 1.4.0.1, as above. Things work better. But, I can’t get System.Web to be recognized by the other projects: “Warning: The reference ‘System.Web’ is not valid for the target framework of the project. (Core Client)”. Any thoughts?

  5. OK – Running MonoTouch 4.0.1 – Just adding the reference System.Web.Services, and the projects all compile without errors.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s