I'm having troubles understanding if I'm properly implementing the MVC pattern in an iPhone app. In my app I have views, view controllers and models. The view controllers manage the interfaces, navigate to other view controllers, set variables to other view controllers and models, and communicate with the models. But this way, am I correctly following the MVC pattern? Don't I miss a model controller?
Another question: I have a User Model that I need to have access to in almost every models and some controllers. Would it be correct to define it as a variable in the appDelegate? I'm all the time reading that this is a bad practice, but I don't see why in this case.
Global objects
All non trivial code has bugs, and they are harder to track if you use dumb global objects. By "dumb" I mean generic objects from the API that lack a single point of access in case you need to log, validate, key-value observe, and notify, changes. You can wrap the global object in a class to route everything through your own accessors.
Some say using globals at all gets you into a bad habit. Others say it depends on the size of your code because it is a trade between development speed and complexity.
The appdelegate is a Singleton, so this discussion is related: What is so bad about singletons? and Singletons: good design or a crutch?.
MVC
Apple talks about it in Cocoa Core Competencies and Cocoa Fundamentals Guide.
One can merge the MVC roles played by
an object, making an object, for
example, fulfill both the controller
and view roles—in which case, it would
be called a view controller. In the
same way, you can also have
model-controller objects. For some
applications, combining roles like
this is an acceptable design.
Is your design complex enough to need a model controller? Whatever your decission is, suffering the consequences will teach you a lot. :)
A design pattern in which the model (any data in your program), the view (what the user sees), and the controller (a layer that handles all interaction between the view and model) are separated in such a manner that modifying either the view or model component of your program has no effect on one another.
The purpose:
The purpose is that later on you may need to change your programs view, and by programming things in this matter you will not have to modify your programs model. Say for instance Apple comes out with an iPad for which the view is programmed somewhat differently than on the iPhone, but you would like to
Now I received some messages after making the video above, some thanking me for making the concept of MVC sound so simple, and others telling me that I had confused them, and wondering how I could understand any of this stuff.
Well, don’t fret.. I’ve seen arguments all over the place as to what components should be classified in the model, the view, or the controller, and I’ve even seen accomplished "guru authors" mess things up when explaining what goes where, just keep in mind that the key idea here is that you can modify one of these key areas without completely wrecking another key area of your program, and leave the rants to the wannabe coders who like to argue about what exactly what fits what acronym, and MVC is often their target.
Related
can somebody explain me the basics of mvc in iphone apps?
I see the template classes, but how do they communicate?
does UIView send events to the Controller? or does the model send events?
what of the template files is the model?
I would strongly recommend the iTunesU, Stanford University series titled "Developing Apps for iOS (HD)" by Paul Hegarty.
Lesson 1 discusses MVC and lesson 2 demonstrates it.
These lessons are free, and well worth a view if you have the time.
The model shouldn't be concerned with the view. The same holds true for the view, it should be decoupled from the model and not really have direct access to it, despite the fact it will be displaying information from the model for the user to see and interact with. The controller acts as intermediary between models and views.
In Apple's words, "A controller object interprets user actions made in view objects and communicates new or changed data to the model layer. When model objects change, a controller object communicates that new model data to the view objects so that they can display it."
From Jeff Atwood's Excellent blog "Coding Horrors":
Like everything else in software
engineering, it seems, the concept of
Model-View-Controller was originally
invented by Smalltalk programmers.
More specifically, it was invented by
one Smalltalk programmer, Trygve
Reenskaug. Trygve maintains a page
that explains the history of MVC in
his own words. He arrives at these
definitions in a paper he published on
December 10th, 1979:
Models Models represent knowledge. A
model could be a single object (rather
uninteresting), or it could be some
structure of objects.
There should be a one-to-one
correspondence between the model and
its parts on the one hand, and the
represented world as perceived by the
owner of the model on the other hand.
Views A view is a (visual)
representation of its model. It would
ordinarily highlight certain
attributes of the model and suppress
others. It is thus acting as a
presentation filter.
A view is attached to its model (or
model part) and gets the data
necessary for the presentation from
the model by asking questions. It may
also update the model by sending
appropriate messages. All these
questions and messages have to be in
the terminology of the model, the view
will therefore have to know the
semantics of the attributes of the
model it represents.
Controllers A controller is the link
between a user and the system. It
provides the user with input by
arranging for relevant views to
present themselves in appropriate
places on the screen. It provides
means for user output by presenting
the user with menus or other means of
giving commands and data. The
controller receives such user output,
translates it into the appropriate
messages and pass these messages on to
one or more of the views.
The best way to understand this (like many core concepts of iOS programming cough HIG cough), is to read Apple's documentation and try it. Here is a good design pattern overview (including MVC) for beginners, including a tutorial: Link
I have three questions related to iPhone and iPad development. I am writing an application for iPhone that should also be available for the iPad in the future. By using the MVC pattern, I know I will keep my models, however it isn't clear for me if I will need to discard the controllers and/or the views. So, my questions are:
1) For those developing the same app for both platforms, what are the best practices? What parts are normally reusable and what parts are normally discarded in order to develop both apps with minimal effort and correct design?
2) Furthermore, I also need to have state/global information in the app. How do you handle (design-wise) "state" information in an iPhone/iPad app? I currently have user information (username and password) that I need to use throughout the application in order to make several server requests (encoded in the http header). In order to achieve that, I have the user model stored in the AppDelegate class. Is this ok in terms of design, or should it be done in a different way?
3) Finally, I have my models separated in abstract classes (or classes handling the generic stuff) and subclasses specializing in different tasks. The idea is writing as less code as possible in order to avoid code repetition (example: sending requests is generic and parsing responses depends on the task at hands). Performance wise, is it a problem to separate the code in several classes and have model inheritance?
Thanks in advance!
1) Well-designed models, views, and controllers should be mostly reusable across iOS devices. The degree of difference in UI design between platforms will largely dictate the reusability of view controllers. For example, when running on iPad, view controllers might be presented in a split view or popover, instead of full-screen, and action sheets presented from bar button items likely won't have cancel buttons.
2) Don't store state in the application delegate. Instead, store it in a model class. Username and passwords in particular should stored in the keychain.
3) Overly-complex class hierarchies can reduce flexibility and make it harder to understand how things work, but don't worry about performance with respect to class hierarchy complexity. Instead, measure performance and spend time optimizing where you'll get the biggest payoff with the least effort. That's unlikely to be superclass method implementation lookup.
So new to objective-c and iphone/ipad development. Trying to get my feet wet with a simple app to connect to one of our apis.
Right now I have a view with a user name and password input and button to submit. When it's clicked I grab those and try to authenticate against our server with a simple post call. I have that working using the NSURL stuff. I originally had it working by declaring the delegate methods for NSURLConnection in my view controller. Once I confirmed it was working properly I knew I needed to get that stuff out of there.
So I created a new class ApiLogin which has a method:
(void)authenticateWithUser:(NSString *)username andPassword:(NSString *)password
which does the post and then this object has the delegate methods declared and handles all that stuff. The next problem I ran in to was how to get any info back to the view controller. Since these were asynchronous calls I couldn't just have my method return data. So after some digging I tried out a solution that seemed to make sense. I created a custom delegate for my newly created class
(void)loginDidFinish:(NSString *)login
Which my view controller declares and uses. This worked perfectly.
So my question now is... am I going down a rabbit hole or is this good? I don't want to create a suite of classes or a class with children classes to handle server communication and data handling with a dozen of these delegate functions if that's bad form. Basically I'm asking, am I doing this right? Is there a better way? I feel like I've been given a new tool, and I see every problem as a chance to use that tool to solve it and don't want to make that mistake. Since I'm really new to iphone/ipad development and it's been a long time since I've done any serious C coding I feel a bit lost with some of this stuff.
That seems fine to me. The other solutions that come to mind would be to have your view controller observe a model object using Key-Value Observation and update accordingly, or to use an NSNotification when login is complete.
It's perfectly reasonable for your view controller to be the delegate for items it is controlling. I would only break it out and make it it's own class if you needed to use the same methods in several view controllers, and the delegate methods were very complicated.
You may find this link helpful, since it seems to be talking about a similar situation to yours where the author used delegates:
http://css.dzone.com/articles/do-not-publishcreating-your
Also, this Apple page might be a good read as well if you are curious about different ways in which objects can communicate with each other:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/CommunicateWithObjects.html
The best way to be confident that you are using the right strategy, beyond simply asking other people for confirmation, is to make sure you understand the definition and purpose behind delegation, and then analyze your code from that perspective to see if its a good fit for what you are trying to do. Excerpt from Wikipedia:
In software engineering, the
delegation pattern is a design pattern
in object-oriented programming where
an object, instead of performing one
of its stated tasks, delegates that
task to an associated helper object.
( http://en.wikipedia.org/wiki/Delegation_pattern )
Considering all that, I think you're on the right track with what you're currently doing.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm giving a presentation on using MVVM in real world applications and I'm including a section on the religious wars design decisions involved when using MVVM as a pattern in your application. In an MVVM application there are two main ways (that I know of) to instantiate a new View/ViewModel pair:
View-First in which you create a view and it creates its own ViewModel and sets it to its DataContext.
ViewModel-First in which you create new view models and create new views in response to changes in ViewModel properties, usually with ItemsControls and/or DataTemplates.
In your experience what are the pros and cons of each method? What do they enable and what problems do you run into with each?
Result Summary
View First - Pros
Easy to track which ViewModel is used by a View
View First - Cons
Doesn't allow a single View to be easily used with multiple ViewModels
Requires extra events to handle communication between Views and ViewModels
ViewModel First - Pros
Allows more complete testing of logic to open new Views and ViewModels
Tends to be DRYer as applications get larger
View and ViewModel are more independent and can be worked on separately more easily
ViewModel First - Cons
More difficult to set up in Silverlight without DataTemplateSelector and typed DataTemplates.
Given the Data Templating feature in WPF, I feel ViewModel-First is the way WPF was intended to be used.
I'll clarify that statement: Data Templating allows you to never instantiate views from your ViewModel. If done correctly, your Views and ViewModels could be kept in seperate projects that DO NOT reference each other. Furthermore, the ViewModel project should not even reference any PresentationFramework assemblies, making your ViewModels consumable by any conceivable user.
I tend to prefer the View-Model first simply because I feel it follows the DRY rule best. When you start creating larger scale applications I find this makes testing easier as well, thus outweighing the initial bit of headache you need to deal with when setting up the application.
Caveat - I use WPF not Silverlight.
By the VM instantiating the V (which is the way I do it) the view is independent and can be used independently of the VM (e.g. in a designer)
Personally, I am veering toward a MVVMC (model, View, ViewModel, Controller) where I have a controlling class which instantiates ViewModels and Views and 'joins them'. The C also then handles getting data (and caching it, etc.) and any communicating across VM and Vs (e.g if a V is instantiated, routes a command to its VM to perform some action, the VM will probably ask the C to perform the action on its behalf; the C can then raise appropriate events which other VMs can handle
If (whether using a controller or not) I need a VM to talk to another VM, it is harder to do so if the V instantiates a VM - because no I have to expose the VM in the V (or at least make some interface available so the 2nd VM can talk to the 1st).
I prefer to use view model first approach. For many reasons:
Vms are your application containing most of logic apart from glue code in form of behaviors or triggers.
If you creates views then you are responsible for its life and cleanup code. You have to deal with threading and other issues which are difficult to test. On the other hand of you create vms and leave the view creation logic with WPF via data template.. you don't have to worry about threading issue. And there will be better separation of concerns.
With vm first approach zero code behind.
With a project level isolation for view and vms you can restrict developers using view specific things like dispatcher in the view model leaving more cleaner and testable code base. I.e view project sprojec to vm. And vm project should not refer to any presentation lib.
If there is clear boundary between view and vm. Both can evolve and will be less fragile.
We've used ViewModel first, but when came in outsourcing, and using of blend became the most important thing, my boss said that View-first is better than Viewmodel-first - I disagreed with him (but one to many is not best ratio of votes ;-) ), because now we have some weirdo connections with events of view in code behind. Now I'm in point of no return and I`ve got stuck in some custom controls - because of the change.
I use a View-first (sort-of) approach. I define the View in collaboration with my client with a dummy viewmodel with test data. When we are satisfied, I proceed to extract an interface from the 'dummy' and implement the real ViewModel. I've found this approach most appealing for the following reasons:
It's fast as prototyping is in-expensive time-wise and I often get it right (ish) in the fourth or fifth try.
ViewModels tend to be easy (easier) to implement when I have an interface to adhere to.
I work in WPF, but I'd think it wouldn't be too different in SL. Also, I never spend time on testing views which may attribute to my choice of approach.
My question is a design issue and it has been driving crazy over the last couple of days. I am new to cocoa touch development.
I have an application that has a UINavigarion controller and a 3 views. I need to keep communicate with a WCF service and store the data on the app side.
How do I create my Model (MVC) in a way that makes the data available to all controllers?
What I started doing is a singleton that handles all the storage and web calls but I read thru the threads that it is a bad idea. I also considered putting the code in the appDelegate but people say that is a bad idea too.
Conceptually how would u design your model and communicate with the controllers?
Any help is much appreciated.
You will get different advice because opinions differ on the best method to use. As you noted, for handling a data model, there are two major design patterns: Dependency Injection and Singleton.
Dependency Injection relies on passing the data model object from view controller to view controller as needed. Marcus Zarra (author of Core Data: Apple's API for Persisting Data on Mac OS X which I recommend) wrote a good article explaining Dependency Injection. Most of the Apple documentation recommends that you use the Dependency Injection design.
I like the Singleton pattern but it is very, very, very dangerous for a novice to use. The Singleton pattern is so easy to do wrong that most graybeards have given up on it and simply advise novices to never use it.
The Singleton pattern has the advantage of increasing modularity and flexibility of the app. However, it requires that you have a firm idea of what the data model will do before you start coding both the Data Model and the UI. It requires more work up front to get correct and it is not as forgiving as Dependency Injection. You have to use singletons with greater discipline.
For a simple app with three hierarchal views, Dependency Injection is the simplest and cleanest design to implement. You won't need the flexibility of a singleton and a singleton will just add unneeded complexity. The Navigation-based template with Core Data provided by Xcode will give you 50% of the app to start. Just add the second and third tier views and you're done.