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"))...but don't forget the linker
{
XmlSerializer serializer = new XmlSerializer(typeof(RogetCategories));
Categories = (RogetCategories)serializer.Deserialize(reader);
}
When 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 Linq
Another 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 ListUse Extension MethodsGetRange (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();
}
Obviously 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"Look ma, no Interface Builder"
{
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;
}
}
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 !and the 'details view' like this:
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);
// no XIB !Look in
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);
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 CODE
This 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.
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:
Wow, another great post, Craig.
ReplyDeleteI tried XmlSerializer a couple weeks ago and it didn't work for me. It wasn't much XML, so I just parsed it with XDocument. With your key tips, I'll try again.
P.S. Thanks for recognizing my blog article about UITableView. Would you mind changing the reference to "Sabon Rai" rather than just Sabon? Sabon Rai is not a person's name; it means "New Life" in an African language I learned growing up in Nigeria: http://www.sabonrai.com/about.html.
Thanks for posting this sample; As usual, it was amazing!
ReplyDeleteThanks guys - having heaps of fun with these little samples, although I feel like I should get cracking on a 'real' app for the AppStore... so many ideas, so little time (outside the "real job")...
ReplyDelete