Wednesday, October 22, 2008

Where does the model go in iPhone MVC Apps?

I've just finished debugging a iPhone demo application for an article. I ran into an interesting problem, however.

Apple's documentation strongly pushes using a Model-View-Controller design for iPhone applications. That's good. Having struggled to debug large applications that didn't use MVC, I definitely see the benefits.

Here, the application should be separated into three distinct partitions. Roughly speaking, the model controls the state. The view displays information to the user, and the Control manages the other two.

In my iPhone app, the views are built in Interface Builder. Each view has its own UIViewController. But, where should the model go? Where should it live? How do I connect it to my view controllers?

Here's the problem, most of the views are instantiated in my code. I can easily pass in the model when I instantiate the class. My root view, however, is instantiated by the nib, secretly and mysteriously in the background.

So far, the best solution I've found is to access the root view in my application delegate as follows:

- (void)applicationDidFinishLaunching:(UIApplication *)application {

model = [[Model alloc] init];

id rootController = [navigationController visibleViewController];
[rootController setModel:model];

[window addSubview:[navigationController view]];
[window makeKeyAndVisible];

This is not as clean as I'd like, but it's better than the other options I've come up with. In particular, there's an intriguing Proxy Object in interface builder, which sounds like an ideal solution--but I can't make it work and I haven't found any documentation on it yet.

If anyone out there has any suggestions, please let me know.



Scott said...

Is this by any chance related to the iPhone app in the Dec issue of MacTech? I am getting nowhere with the "model" in the viewDidLoad function of the MainViewController.m.

The system simply continues to tell me that "Model" and "model" are undeclared.

Artur said...

Just #import "Model.h" in your MainViewController implementation.

The application works well as described.

Maxincube said...

Try using singleton pattern on model class, then you can access the model from any view controller class without reinstantiate it.