Developing for iPhone – Part 4: Controlling the Hubble Space Telescope with MVC
So for this part of the series, I wanted to explore MVC by writing a sample application that reuses code between an iPhone app and a WPF windows application. The goal here is to lessen the amount of code required to be written on the iPhone, because what developer wants to use a Mac, right? But this should also cut down development time, too, and should make it easier to port the same app to Windows Phones or other platforms.
So what should our app do? Why not measure some planets? Let’s make a little app that contacts the Hubble space telescope to get an updated measurement of each planet. The operation will take a little time and will run in the background with a progress indicator, and when completed, will populate a list for the user to see.
Well… we will not really contact the Hubble telescope, but let’s write a simple Model class to simulate it:
Simple enough right? In real life, our Model class would be a little more complicated: running SQL queries, contacting web servers, etc. This should be plenty for us to demonstrate MVC.
So to utilize this in a MVC application, we need 2 more pieces: the Controller and the View.
Our WPF app will be setup like so:
- We’ll write some Xaml code with a ListView, refresh Button, and some kind of progress indicator—this is the View.
- We’ll write a TelescopeController class that exposes everything the View needs to function: a collection of planets, a “Refresh” command, and an “IsBusy” property—this is the Controller.
NOTE: in reality this is the MVVM pattern, let’s ignore that for the sake of this article.
So a snippet of our View:
And our Controller:
Simple enough for WPF, right? (I used a few helper classes in here, check example code at the bottom)
Here’s what we have to do for the iPhone:
- Create a View in Interface Builder (IB): in the UIWindow, we’ll add a UITableView, UIBarButtonItem to refresh and a UIActivityIndicatorView for progress
- Still in IB, we have to hook up a UITableViewController with a “Refresh” action and an “Outlet” for the indicator
- In MonoDevelop, we setup a TelescopeController that inherits UITableViewController
- We also have to implement UITableViewSource to populate our UITableView
- Next we have to explicitly interact with all of our View objects within the controller
Here’s the full code for the TelescopeController for iPhone:
Seems a little more complicated, right? And there’s definitely some stuff in here that seems fishy to me.
What is wrong with Apple’s version of MVC:
- Everything is very tightly coupled:
- --> Controllers are created in IB, just like the View
- --> View objects are completely accessible from within the controller, this is also the only way that controllers can interact with the view—directly
- --> So you can’t really re-use controllers across a WPF app and an iPhone app (nor Android for that matter)
- Unit testing your controllers on the iPhone is just not possible
- --> It is possible to use NUnit in MonoDevelop, but to run NUnit on the iPhone or in the simulator, someone would need to port NUnit to iOS (not something anyone has tackled yet).
- --> You can’t use the iOS SDK while running Mono on the Mac, and all your controllers directly use iOS View objects, so testing almost goes out the window here. You really can only test your Model classes in MonoDevelop, and why not just set that up in Visual Studio on Windows?
- Apple’s iOS SDK seems overcomplicated for no reason
- --> You have to inherit UITableViewController and UITableViewSource just to get a simple list to be displayed. Yeah it is very flexible as far as what you can do with it, but has way too much boilerplate code to get setup.
- --> Various Attributes must be set to hook up your controllers to what you setup in IB, and messing these up cause poorly worded error messages (crashes) at runtime.
- Controllers are setup in IB, pushing MVC into the UI design.
- --> To me, this seems like it would hinder a graphic designer from designing views for an iPhone app, as it requires them to understand the MVC design pattern to know what is going on.
- --> In WPF, a designer could easily create Views in Expression Blend and only have to setup bindings to the different properties or commands—something they could even leave out for the developer to come in and setup later. You just can’t do this when developing for iPhone.
- --> Interface Builder is also painful to use for a Windows developer in general: you have to drag things around, and attach weird little lines, etc. (You have to try it to see what I mean here, but I think I threw up a little when I used IB the first time around).
- You have to use a Mac to develop with… Need I say more!
Well, did Apple get anything right?
- At least they’re using MVC
- Hooking up the command (Action) for the Refresh button is pretty easy and intuitive (passing in the UIBarButtonItem is actually optional).
- The default look of most UI controls are great, in reality you don’t need a graphic designer to do too much to develop an aesthetically pleasing app.
At least Novell ported enough of the .Net base class libraries to where we could completely reuse our Model classes with no additional work whatsoever.
For full code examples, check out: Hitcents Examples on Codeplex
Depressed on learning to develop for the iPhone? Well, there are some tricks you can do to clean up MVC on the iPhone, which has definitely called for some deep thinking on my part.
Next time I’ll simplify the iPhone app to be as elegant as possible, hook up IoC containers in both applications, promote the WPF app to using the Caliburn MVVM framework, and even setup unit testing. I bet you guys just can’t wait!