This sample was inspired by
Roget’s Hierarchical Thesaurus in a Silverlight App. I highly recommend you check out the
Silverlight Thesaurus 'visualization' as it will give you some idea about why it seemed like a good match for the iPhone UINavigationController (ie. a hierarchy). The fact that it's not a uniform depth just makes the problem more interesting.
Charles very generously provided me with the source data he worked on to produce the Silverlight app (and the associated C# classes). It's great that MonoTouch allows existing .NET source to be re-used so easily.
Here are some screenshots of the iPhone app:
Xml de-serialization is easy...Loading 2.6Mb of Xml data into an object graph is
so easy with the
System.Xml.Serialization
support in MonoTouch!
using (TextReader reader = new StreamReader("roget15aCategories.xml"))
{
XmlSerializer serializer = new XmlSerializer(typeof(RogetCategories));
Categories = (RogetCategories)serializer.Deserialize(reader);
}
...but don't forget the linkerWhen you create the classes you will be de-serializing "into", don't forget to mark them with the
MonoTouch.Foundation
attribute
[Preserve(AllMembers=true)]
. This prevents the compiler/linker from 'optimising away' parts of your class that don't "appear" to be referenced in code (eg. the constructor) because they are only getting called at runtime as part of the deserialization process. Instead of marking the class declaration, you could alternatively mark specific members with
[Preserve]
to give you greater control over the final output.
Use LinqAnother great piece of .NET support is Linq. It isn't referenced in MonoDevelop MonoTouch solutions by default, so don't forget to right-click your
References and tick
System.Xml.Linq
then add the
using
clause and Linq away...
public List GetRange (string start, string end)
{
Console.WriteLine("Get {0} to {1}", start, end);
var l = from c in Categories
where c.Index >= start.ToNumber() && c.Index <= end.ToNumber()
select c;
return l.ToList();
}
Use Extension MethodsObviously if Linq works, so do extension methods.
ToNumber()
is a very simple (contrived, even) example of an extension method in MonoTouch:
public static class RogetExtensions
{
public static int ToNumber(this string num)
{
string s = num.Replace("a","");
int index;
if (int.TryParse(s, out index))
return index;
else
return -1;
}
}
"Look ma, no Interface Builder"As I .NET developer I usually shun the design surface (in Xaml you don't really have a choice) so I was keen to try building an iPhone app without Interface Builder. It's a little difficult knowing where to start, but this
UITableView in code example was immensely helpful.
There are four
ViewController
s, and the basic format is the same for each: inherit from UIViewController (or a subclass), build up some controls in
ViewDidLoad()
and implement any additional delegates required.
The scrolling table views look like this:
// no XIB !
tableView = new UITableView()
{
Delegate = new TableViewDelegate(Classes, this),
DataSource = new TableViewDataSource(Classes, this),
AutoresizingMask = UIViewAutoresizing.FlexibleHeight|
UIViewAutoresizing.FlexibleWidth,
BackgroundColor = UIColor.White,
};
tableView.SizeToFit();
tableView.Frame = new RectangleF (
0, 0, this.View.Frame.Width, this.View.Frame.Height);
this.View.AddSubview(tableView);
and the 'details view' like this:
// no XIB !
webView = new UIWebView()
{
ScalesPageToFit = false
};
webView.LoadHtmlString(FormatText(), new NSUrl());
webView.SizeToFit();
webView.Frame = new RectangleF (
0, 0, this.View.Frame.Width, this.View.Frame.Height);
this.View.AddSubview(webView);
Look in
MainViewController.cs
and
AppController.cs
to see how they are all wired together. The other ViewControllers pass around a reference to
MainViewController
so they can call
mvc.NavigationController.PushViewController (????, true);
which makes the navigation work (automatic 'back' buttons, animation between views, etc). I've no idea if this is the
best way to do it, but hey it works :)
THE CODEThis sample code would not have been possible without the hard work of others. It also uses
content which can have copyright/ownership implications.
- Thank you to Charles Petzold for (a) researching/parsing the text (b) writing and supplying the .NET classes used to access it and (c) allowing his work to be included in this derivative
- Acknowledgement to Project Gutenburg for providing the original text. The copyright status is listed as Not copyrighted in the United States. If you live elsewhere check the laws of your country before downloading this ebook. - I presume the same applies to users of this derivative work
- Sabon Rai MonoTouch posts including UITableView in code taught me a lot.
Anyway, you can
download the
MonoDevelop solution and try it for yourself.
These two class diagrams show the structure of the code. The first shows the classes that are used to deserialize the Xml data:
while this shows the application and viewcontroller implementations: