MVC Communication Rules

From the excellent Stanford University iOS course, fall 2011 (free on iTunesU). This diagram from the presentation summarizes the rules and methods of communication between the Model, View and Controller components of an iOS app.

MVC Communications

MVC Communication Channels and Methods

  • Model = What your application is (but not how it is displayed)
  • Controller = How your Model is presented to the user (UI logic)
  • View = Your Controller‘s minions.
  • Contoller‘s can always talk directly to their Model.
  • Controller‘s can also talk directly to their View.
  • The Model and View should never speak to each other.
  • Communication between the View and Controller is “blind” and structured.
  • The Controller can drop a target on itself, then hand out an action to the View.
  • The View sends the action when things happen in the UI.
  • Sometimes the View needs to synchronize with the Controller.
  • The Controller sets itself as the View‘s delegate.
  • The delegate is set via a protocol (i.e. it’s “blind” to class).
  • Views do not own the data they display.
  • So, if needed, they have a protocol to acquire it.
  • Controllers are almost always that data source (not Model!).
  • Controllers interpret/format Model information for the View.
  • The Model is (should be) UI independent and should NEVER talk directly to the Controller.
  • If the Model has information (e.g. an update) it uses a “radio station” – like broadcast mechanism that Controllers (or another Model) can “tune in” to for stuff they’re interested in.
  • A View might “tune in” to a “station”, but probably not to a Model‘s.

Stick to these rules when building your application and you will have a much better chance of understanding the monster you’ve created(!).

MVC based application

MVC based application

Using and Abusing UIViewControllers

Jonah Williams has some life changing advice on the proper and improper use of UIViewControllers in his post here. This post will switch on the light bulb for anyone coming to iOS development from another platform such as .NET.

This is his (and Apple’s) advice In a nutshell:

  • One (and only one) view controller should be responsible for a whole hierarchy (or screenful) of UIViews.
  • Mostly, you should only use one view controller per screen. Essentially the rootViewController of the current UIWindow should be the only UIViewController with a visible view.
  • Each different screen should have a different view controller i.e. one controller should not control more than one screen.
  • You should NOT nest custom UIViewControllers within a view hierarchy.
  • If more than one UIViewController hangs off the application’s UIWindow, only one of these will get the messages for changes in orientation. The other(s) will NOT get these messages.
  • Nested UIViewControllers are not guaranteed, or likely, to receive messages for changes in orientation or lifecycle messages such as viewDidAppear:, viewWillAppear:, viewDidDisappear: and viewWillDisappear: even though they inherit from UIViewController. Only the topmost UIViewController is certain to get these messages.

Some interesting discussions on this point on StackOverFlow:

iPhone viewWillAppear not firing

Am I abusing UIViewController Subclassing? – Nice quote from this:

Each screenfull should have one master VC Subclass, with all the subviews controlled instead by custom controllers (which happen to control views) which are subclasses of simple NSObject.

In this case, UIViewControllers should only be directly to the Window or UINavigationController, UITabBarController etc?

Also, this quote from Apple’s View Controller Programming Guide:

View controllers are directly associated with a single view object but that object is often just the root view of a much larger view hierarchy that is also managed by the view controller. The view controller acts as the central coordinating agent for the view hierarchy, handling exchanges between its views and any relevant controller or data objects. A single view controller typically manages the views associated with a single screen’s worth of content, although in iPad applications this may not always be the case.

With iOS 5 and the introduction of Custom Container View Controllers, much of this will change (see Pat Zearfoss’s comment, below). But it is important to understand the above as a starting point.

Efficiently Returning Paged Data from T-SQL

Using a Common Table Expression (CTE) provides a very efficient way to return paged data along with a total row count from Microsoft SQL 2008.

Here, we assume @PageNo and @PageSize have been set by the caller. @PageNo is the page number for which we wish to return rows. @PageSize is the desired number of rows per page.

-- Calculate the ROW_NUMBER() range we wish to return...
DECLARE @StartRow INT = ((@PageNo - 1) * @PageSize) + 1
DECLARE @EndRow INT = @StartRow + @PageSize - 1

;WITH cols
AS
(
SELECT number,
ROW_NUMBER() OVER(ORDER BY number) AS seq
FROM tallynumbers
)
SELECT number, (select count(*) from cols) as TotRows
FROM cols
WHERE seq BETWEEN @StartRow AND @EndRow + 49
ORDER BY seq

NOTES:
The T-SQL command ROW_NUMBER() is “one-based”.