Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Organizing iOS project for MVC design pattern

I'm working on a multiview app for iPhone and currently have my views (VIEW) set up and their transitions (CONTROLLER?) working nicely. Now I'd like to add objects for the actual program data (MODEL).

My question is: How should I structure my data to adhere to the Model View Controller (MVC) design pattern? I know I should create separate classes to implement my data structures and that my controller classes can pass messages to them from the view, but are there any other organizational considerations I should examine? Especially those particular to Cocoa Touch, Xcode, or iOS?

Other particulars: Playback of pre-recorded and perhaps user-generated audio will also be essential. I know these are model elements, but how exactly they relate to the "V" and the "C" I'm still a bit fuzzy on. I suppose when a user action requires audio playback, the CONTROLLER should pass a message to the MODEL to ready the appropriate sounds, but where exactly should regulation of the playback live? In a "PlayerController" separate from the ViewController I imagine?

Many thanks and pardon my MVC noobery.

like image 720
Old McStopher Avatar asked Mar 08 '11 03:03

Old McStopher


2 Answers

Caleb gives a good introduction and overview of how to think about the problem. In your particular case, here are some of the pieces you would might have given your description:

  • Clip (M) - Responsible for holding the actual audio data. It would know how to interpret the data and given information about it, but it wouldn't actually play anything.

  • Player (V) - Actually plays a clip on the speakers. Yes, that's a kind of view in MVC. Audio is just another kind of presentation. That said, you'd never call it "PlayerView" because that would suggest it were a subclass of UIView.

  • PlayerView (V) - A screen representation of the Player. Knows nothing about Clips.

  • ClipManager (C) - An object that would keep track of all the clips in the system and manage fetching them from the network, adding and removing them to caches, etc.

  • PlayerViewController (C) - Retrieves a Clip from the ClipManager, and coordinates a Player and a PlayerView to display and play it, as well as any other UI elements (like a "back button" or the like).

This is just an example of how you might break it down for some theoretical audio player app. There are many correct MVC ways to do it, but this is one way to think about it.

like image 131
Rob Napier Avatar answered Oct 18 '22 23:10

Rob Napier


Lord John Worfin (and, I'm sure, someone before him) said: "Character is what you are in the dark." Well, a model is what an application is when nobody is looking -- it's the data and logic that defines how the app behaves regardless of how it's presented on screen.

Imagine that you decide to add a command-line interface to your application. You'd still want to use the same structures for managing your data, and your logic for sorting, sifting, and calculating based on the data should still be the same too. The code in your app that remains important/useful no matter how the user sees or interacts with the app is the model.

A model can be very simple and made up entirely of standard objects. iOS apps are often more about retrieving, storing, and displaying data than they are about crunching numbers, so it's not unusual to have a model that's just an array of dictionaries, or a hierarchy of dictionaries that's several levels deep. If you look at Core Data's NSManagedObject class, it's similar in many respects to NSMutableDictionary. So, don't be afraid to use standard objects if they're appropriate.

That said, you can certainly also create your own model objects, and that's useful if you have certain requirements that you want to enforce on your data, or if you want to be able to derive information from the data.

Beginners often wonder how each controller gets access to the model. Some folks advocate using the singleton pattern for this, mainly because it provides a single, shared, globally accessible object. I don't recommend this. Instead, have some high-level object in your app such as the app delegate create/load the model (which will likely be a graph of many individual objects) and give a pointer to the model to any view controllers that need it. If those controllers in turn create other view controllers, they can again provide a pointer to the model (or part of it) to their child controllers.

I hope that helps.

like image 27
Caleb Avatar answered Oct 18 '22 23:10

Caleb