This is the first part of a two-part tutorial showing you how to create a simple RSS Reader application for the iPhone using C# and MonoTouch. The application will use a UINavigationController to navigate back and forth between a news list (in a UITableView) and a second view showing more details about the news article that the user selects.
In this part of the tutorial we are going to:
- Create a UINavigationController, with a UITableViewController inside it.
- Show a list of News Articles in the UITableView, which are taken from an RSS Feed
Firstly, create a new solution in MonoTouch called RssReader.

Double-click "MainWindow.xib" which should launch Interface Builder. Our first task is to find a UINavigationController in the Library, and drag it onto the window with the title "MainWindow.xib". I recommend using the tree view mode in this window, not the icon view. After you drop your UINavigationController in there, it should look like this:

Once that is done, we need to create an outlet in Interface Builder, so that we can work with our UINavigationController in our C# code. To do this differs slightly depending on which version of Interface Builder you have installed, but in the latest version (at the time of writing) this is done in the Library window (it used to be done in the Inspector window). In the Library window, I need to select "Classes" at the top, then select "AppDelegate" in the list, and finally select "Outlets" at the bottom. By clicking the + button we can add a new outlet. I'm going to name it "navigationController", and once you're done you should have something looking like this:

After creating the outlet, it's not actually connected to anything yet - so now we need to connect it to our UINavigationController. In the Inspector window, on the Connections tab, you should see your outlet, and an empty circle next to it, meaning it's not connected to anything yet. Drag that circle to your UINavigationController to make the connection.

Note that I'm dragging from right to left in the diagram above: connecting the outlet to the UIViewController (NOTE: I originally forgot this step in the first version of this tutorial - thanks for pointing it out Bruce).
After this is done, I'm going to find an item called UITableViewController. This is where we will display news articles that we have taken from an RSS feed. Drag it directly onto the Navigation Controller that we created earlier. You can drag it into the navigation controller in the "MainWindow.xib", or do it directly onto the designer. Once you're done with that, you should have something that looks like this:

This time, we are not going to create an outlet directly, but instead we are going to give it a class name. We haven't created this class yet, but we will do shortly. Type "MyTableViewController" into the class identity, like this:

Remember, we haven't created this class yet, but that is our next task. For now, we are finished with Interface Builder. Save, and quit.
Okay, so now we should be back in MonoDevelop, ready to write some code. Create a C# class called "MyTableViewController.cs". This is the class that we have already told the UITableViewController to look for. I suggest you go to the Code Snack blog post on UITabBarController and add the template for a UITableViewController. Once the template is added, if you delete all of the code in a new class and type "uitvc" and click Tab on your keyboard, you end up with a standard template for a UITableViewController:
using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace RssReader
{
// [MonoTouch.Foundation.Register("MyTableViewController")]
public partial class MyTableViewController : UITableViewController
{
static NSString CellID = new NSString ("MyIdentifier");
// Constructor invoked from the NIB loader
public MyTableViewController (IntPtr p) : base (p)
{
}
// The data source for our TableView
class DataSource : UITableViewDataSource
{
MyTableViewController tvc;
public DataSource (MyTableViewController tableViewController)
{
this.tvc = tableViewController;
}
public override int RowsInSection (UITableView tableView, int section)
{
return 1;
}
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell (CellID);
if (cell == null)
{
cell = new UITableViewCell (UITableViewCellStyle.Default, CellID);
}
// Customize the cell here...
return cell;
}
}
// This class receives notifications that happen on the UITableView
class TableDelegate : UITableViewDelegate
{
MyTableViewController tvc;
public TableDelegate (MyTableViewController tableViewController)
{
this.tvc = tableViewController;
}
public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
{
Console.WriteLine ("Row selected {0}", indexPath.Row);
}
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
TableView.Delegate = new TableDelegate (this);
TableView.DataSource = new DataSource (this);
}
}
}
It's very useful to get all of that code for free. The key things to note here are:
- There is a nested class called DataSource. This class has two important methods called RowsInSection and GetCell. We will use both of these later.
- There is another nested class called TableDelegate. This handles things such as when the user selects a row (the RowSelected method). Later, we will navigate to another view and show details on the story that the user selected.
- Finally, there is a method called ViewDidLoad. This will be useful, because it will be here that we will fetch the news stories from an RSS feed.
NOTE: at this point, check and see if your MainWindow.xib.designer.cs file has a partial class definition for MyTableViewController, decorated with a Register attribute. Mine did (it was generated automatically) but for some readers this didn't happen (see the comments). If not, simply decorate your MyTableViewController class with the Register attribute (it is commented out in the sample above.
If you run this app right now, it should build but you will see nothing, just an empty screen, not even our UINavigationController. That's because we haven't told it to load the navigation controller yet! If you remember, we created an outlet called "navigationController" at the start, in Interface Builder. If you go to the Main.cs file in MonoDevelop, you will see a method called FinishedLaunching. It is here that any startup views need to be added. There might already be a line commented out that does what we want. Either way, make sure we now have this code in the FinishedLaunching method:
// This method is invoked when the application has loaded its UI and its ready to run
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
window.AddSubview(navigationController.View);
window.MakeKeyAndVisible ();
return true;
}
At this point your app should run and look like this:

This what we should expect. We can see the navigation at the top, and we can see the table in the middle, the only thing we lack is the data. Let's do that now. Firstly, create a new C# class called NewsArticle.cs like this:
using System;
namespace RssReader
{
public class NewsArticle
{
public string Headline { get; set; }
public string Content { get; set; }
}
}
Let's head back over to our MyTableViewControllerClass and get the real data and bind that to the table. Create a generic List<NewsArticle> right at the top of the class:
public partial class MyTableViewController : UITableViewController
{
List<NewsArticle> NewsArticles;
...
We will fill this list with the real data in the ViewDidLoad method. I am going to use LINQ and the System.Xml.Linq namespace here to populate the List of NewsArticles. As you can see, I have hardcoded the RSS Feed URL. I am using the BBC Tottenham Hotspur feed because that's the news I'm interested in, but you can use anything you want:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
XDocument rss =
XDocument.Load("http://newsrss.bbc.co.uk/rss/sportonline_world_edition/football/teams/t/tottenham_hotspur/rss.xml");
var query = from item in rss.Descendants("item")
select new NewsArticle
{
Headline = (string) item.Element("title"),
Content = (string) item.Element("description")
};
NewsArticles = query.ToList();
TableView.Delegate = new TableDelegate (this);
TableView.DataSource = new DataSource (this);
}
XDocument is in the System.Xml.Linq namespace - you will need to right-click of References in your project and add it. Then you will need to add a using directive at the top of your code file to that namespace, and also to System.Linq.
using System.Linq;
using System.Xml.Linq;
The RowsInSection method is currently hardcoded to "return 1" but we want it to return the dynamic length of our news article list. Let's change it to this:
public override int RowsInSection (UITableView tableView, int section)
{
return tvc.NewsArticles.Count;
}
And one final adjustment is to set the text of each cell in the table. We already have a comment that says this:
// Customize the cell here...
Change it to this:
// Customize the cell here...
NewsArticle article = tvc.NewsArticles.ElementAt(indexPath.Row);
cell.TextLabel.Text = article.Headline;
We are now finished with part 1. You can see the result here:

You can actually see slighly more than just the simulator in that last screenshot. You can also see the Application Output window. It shows that we are using Console.WriteLine to print which row was clicked when the user taps a row. This will become important in the next part of this tutorial, when instead of doing a Console.WriteLine, we will use the NavigationController to navigate forward to a new view, where the user can read more details about the news article that they selected.
Hope you liked part 1 of this tutorial and found it helpful. Head on over to part two and finish the app by navigating to a second view.
I hope you found this tutorial helpful. Any questions or feedback are appreciated in the comments.