Recently I've been reading up on the MVC pattern and wish to apply it to my iPhone development. However, there seem to be so many variations of the pattern that I'm not sure exactly how it should be applied.
As far as I gather, the view will notify the controller of any actions which have been performed and the controller will in turn update the data model (if required). The data model will notify the view whenever a change to the data occurs and the view then updates it's display of the data appropriately.
In this basic model, the controller only has knowledge of the data model. However, I can't seem to figure out how to employ this design within my iPhone app.
The following page suggests an alternative version of the pattern where the controller has an awareness of both the data model and the view and all communication between the model and view is performed via the controller. It also seems to suggest that the model and view have access to the controller. Would I be right in suggesting that the data model interacts with the controller via some form of notification (notifications or KVO) and that the view interacts with the controller via actions?
Is this second model correct?
http://www.bogotobogo.com/DesignPatterns/mvc_model_view_controller_pattern.html
Many thanks,
Danny
I found Paul Hegartys explanation on MVC in iOS very helpful. see his Stanford iTunes U video. MVC starts at minute 22.
edit
The link of the video doesn't bring you there as expected. it is 1. Introduction to Cocoa Touch, Objective-C, Tools, and MVC (September 21, 2010)
MVC has been around for a long time so there are many variations (or misquotes) to the pattern. Although, the concepts are much the same for most MVC implementations I have seen.
I would focus on how Apple defines MVC. Which can be found in the Cocoa Design Patterns guide and from sample code downloaded from the SDK site (MVCNetworking example).
With iOS you will often will have Models and ViewControllers(which are a merged role of both the controller and the view).
Also, Martin Fowler has some great MVC stuff in his GUI Architectures.
iOS development is very much orientated towards the MVC pattern.
It is usually done with viewControllers and a model. The view is build in Interface Builder, assigned to the controller and the model part is retrieved from elsewhere.
I would say that for Cocoa-Touch the second "version" of the pattern is the one that best describes what usually goes on.
The idea behind MVC is that the model and the view is reusable, but the controller is often fitted to the problem at hand.
This is also true for iOS development, especially if you use interface builder.
The view is hooked up to the viewController via actions/delegates and the model either broadcast its changes through KVO notification or by the controller pulling new data.
There is tons of code available from Apples developer portal and you should start out by looking at some of that code. Having your eyes and mind tuned to looking for the MVC pattern you will see they use it constantly, with the delegate pattern on top to provide event better abstraction
In my opinion, second one is better. Model and view should be separated completely. If view receives notification from model, the view will depends on design of model. By placing controller here, tightly coupled circular-dependency created.
Finally, each part cannot be developed independently, divide-and-conquer strategy is just impossible to use.
My advise for general cases:
Make view and model passive and independent as much as possible. Major mutation must be done with only external manipulation. It should not be changed actively.
Make controller actively controls both of them and other controllers.
In iOS, a UIView is a view which is fully passive. In most cases, all major mutation always done externally by UViewController. And model part should be implemented yourself completely as you want. (Or you can integrate models into controller if it's small enough, however, I don't recommend it)
In some big featured UIView, a sub-scale MVC patterns are used. Fractal!
Related
I'm having a hard time wrapping my head around MVVM as I'm in the progress of learning SwiftUI development with Swift for iOS. After reading various tutorials and watching YouTube videos, this is my understanding:
View: The UI
Model: Data layer
ViewModel: "Glue" between view and model. Contains business logic.
However, after doing additional research, I found this article which talks about the role of controllers in MVVM. Now, this confuses me a lot because my understanding was that the ViewModel in MVVM already takes care of what a controller would do e.g. in MVC and therefore controllers would not exist in apps based on MVVM.
Question: Do controllers exist in apps based on MVVM or is the article simply wrong?
It is merely a question of terminology. This author’s choice of terminology is a bit unusual, and I would not get hung up on that. As you dive into these architectural patterns, you’re going to see all sorts of different uses of terminology. (Usually it is the term “view model” that is subject to some creative interpretation.)
Regarding this author’s particular use of the term “controller”, earlier in the document, when talking about view controllers, he starts referring to them as simply “controllers”. This is imprecise, but it is the terminology that he adopts throughout the article.
(As an aside, I would avoid referring to view controllers just as “controllers”, because for many of us, the term “controller” refers to something far more abstract, unrelated to the UI. E.g., see the discussion of “controllers” late in Dave Delong’s excellent video A Better MVC. But let’s set all of that aside and talk about the role of view controllers in MVVM.)
If you are employing MVVM in UIKit or AppKit, then you have a model, a view, and a view model. But you still have view controllers, too. So what happens to them? They do not disappear (unless you switch to something like SwiftUI).
Most/many of us simply consider the view controller as part of the broader “view” layer. A view controller is a UIKit object. It configures views. It is not some abstract object, but rather is an integral part of the UI. In MVVM, it often bears responsibility for hooking up the views to the view model, etc. Regardless of what architectural pattern you adopt, the hallmark of a good view controller implementation is that it is almost entirely restricted to UI related tasks.
So, in short, in that article you reference, the author is merely saying that view controllers are still in the mix (for non-SwiftUI projects, at least). He decided to describe it as a separate layer in his MVVM diagram. Many of us just consider the view controllers to just be part of the “view” layer. It is a question of terminology.
I am trying to keep to the Apple MVC design pattern where the view receives input and passes it on to the controller. To keep the controller thin and to avoid it turning into a bloated GodClass doing all the work, I am attempting to create a subclass of UIView and to receive user input there to be passed to the controller for processing. But I am running into problems with how to best do this in Swift.
In order to pass the user input from the view to the controller my UIView subclass will need to communicate with the associated ViewController, but I've seen posts on SO about how that is not recommended. This Q&A, for example, advises that this is bad but suggests a delegate approach. A comment from the same Q&A also notes that this is bad.
Apple's own MVC example doesn't demonstrate a separate UIView subclass, but uses the existing UITableView, which is all coded within the parent UIViewController, making it a bloated, rather than a thin controller.
How to best approach this?
I recommend you read the apple's doc on MVC pattern since I noticed you do not really understand the principle of the pattern: Model-View-Controller
In order to build lighter ViewController, look at this issue: Lighter View Controllers
You may also interested in MVVM (which used in Cocoa&CocoaTouch for VC thinning)
have a look at this article: Introduction to MVVM
Your experience with bloated View Controllers is not necessarily the fault of your misunderstanding the MVC pattern. The iOS developer Ilya Punchka writes about this in his tutorial post about View Controller Thinning and writes:
A lot have been said on this topic already, even more will be said in future cause unfortunately there is no silver bullet and view controller still stay massive in many projects. Recently Andy Matuschak presented Let's Play: Refactor the Mega Controller! a live coding session on this topic. So you can see it's a well know and still actual problem.
The situation isn't helped by Apple's sample code which also demonstrates massive view controller syndrome! Check out the above links (although the first is in Swift 2.0 and I've had troubles updating his dependancies to Swift 3.0), they both give useful oversight on some ideas around this subject.
I'd recommend taking a look at LetsBuildThatApp episode "Swift: Firebase 3 - How to Refactor View code out of Controller (Ep 23)" here:
https://youtu.be/F3snOdQ5Qyo
Shows a pretty good way to refactor the View code out of the Controller.
I'm new to iphone development. There's a lot of books on this topic available. But most of the beginner's guides are mostly concerned with Interface Builder usage and lack the information about existing built in XCode code templates or something that could help me in understanding MVC implementation in code. I found that it is possible to write working iOS program without ViewController at all. Well, it seems to me like that after working with the sample code called ViewTransitions.
So, the question is - why is that possible to avoid ViewController implementation in a program that has an interface with a button? If the answer is going to be too long, could you please recommend kind of tutorial or manual covering this topic.
Thanks in advance.
#user697562's answer is essentially correct: in the case of ViewTransitions, the role of the controller is played by the app delegate. The app does next to nothing -- it just switches betweeen two views to demonstrate several possible transition effects -- so a UIViewController isn't really needed there.
Notice that there's also nothing in ViewTransitions that you could really call a model object. If you're looking for a strong example of MVC, ViewTransitions isn't the best project to look at. Other sample projects, such as TheElements, give a better demonstration of MVC in action.
There is a concept called delegation. A concept which helps maintain MVC. It helps to keep the model separate from controllers. For eg: - UITableView/UICollectionView , which knows how to display the data and other ui stuff.
But it does not know which cell to display or what data to display at a particular index. And this is where delegation and the delegate object comes into place. UICollectionView handles all the view part whereas all the non view part is handled by the delgate object, which gives the required data for the view. This way a delegate(usually a separate view controller) acts as a data source and UICollectionView as a ui renderer.
in ViewTransitions, there IS an App Delegate, which is kind of your sole "controller". Even ViewTransitions has:
transition.delegate = self;
IOS is a bit different from some frameworks in that you aren't as "in control" of what is going on. It often uses a delegation model where you set your code as the delegate, but it (IOS) is in control. Still, you can write in MVC style, it's just your "C" isn't fully in charge.
There are tons of resources concerning coding on the iPhone. Most of them concern "how do I do X", e.g. "setup a navigation controller", or "download text from a URL". All good and fine.
What I'm more interested in now are the questions that follow the simpler stuff - how to best structure your complex UI, or your app, or the common problems that arise. To illustrate: a book like "Beginning iPhone 3 Development" tells you how to set up a multi viewcontroller app with an top 'switcher' viewcontroller that switches between views owned by other view controllers. Fine, but you're only told how to do that, and nothing about the problems that can follow: for example, if I use their paradigm to switch to a UINavigationViewController, the Navigation bar ends up too low on the screen, because UINavigationViewController expects to be the topmost UIViewController (apparently). Also, delegate methods (e.g. relating to orientation changes) go to the top switcher view controller, not the actual controller responsible for the current view. I have fixes for these things but they feel like hacks which makes me unhappy and makes me feel like I'm missing something.
One productive thing might be to look at some open source iPhone projects (see this question). But aside from that?
Update
To clarify: I suppose what I'm asking about could be summarised as "Recipes and Gotchas for iPhone development". The sort of things that are of interest to developers, but aren't covered in any of the iPhone books etc. that I've seen, such as:
I'm writing an iPad app and want a UISplitViewController presented to the user only some of the time, which Apple seem to be saying I can't do. Is it possible? How?
Apple don't give me a way to stylise my app in a convenient, across the board way (e.g. font tweaks, or colours). How can I approach styling my app?
Memory management isn't made any easier by some of the inconsistencies in UIViewController method names (e.g. viewDidUnload is not the opposite of viewDidLoad, despite the name). Is there a consistent easy way to tidy that up and make view controller memory management less error prone?
How can I consistently and easily test my view controllers for behaving correctly when a memory warning comes in? It's easy to simulate a memory warning in the Simulator, but if the UI I want to test is showing (and is a 'leaf level' view controller), it won't get its view unloaded because it is currently visible.
N.B. I'm not actually asking the above questions here -- I think I have decent answers to them! -- just giving examples of 'good' questions that illustrate this stackoverflow question.
The WWDC talks available on iTunes U (at http://developer.apple.com/videos/wwdc/2010/) have some great information about structuring, especially in the Application Frameworks section.
If you're talking about code, use the Model/View/Controller pattern like in most Web applications:
The model code defines the objects that your program represents. A time tracker app, for example, might have model objects like Task, TimeSlice, and User (especially in a network setting).
The view code is provided for "free" with the iOS SDK, unless you need specialised view code. These are UIImageView, UIButton, etc.
The controller code bridges the 'gap' between the model and view. The controller will change the views to reflect the model selected by the user and facilitate the selection of model objects.
This is the base design pattern for any iPhone app, and it's the one that most will use.
If, on the other hand, you refer to what we in my company call UX (user experience) design, however, you can't beat the Apple HIG guidelines in the Apple iOS SDK documentation set, available online or in Xcode from the Help menu.
The other thing I recommend quite highly is to play around with some test/dummy code. Nothing can top experience. Experimenting with the iOS SDK and getting your hands dirty will allow you to truly learn the best ways to design apps.
Edit:
Also, delegate methods (e.g. relating to orientation changes) go to the top switcher view controller, not the actual controller responsible for the current view.
Can you clarify? In all of the apps I've written, the currently shown view controller receives the orientation change methods. Note that there are two methods. shouldAutorotateToInterfaceOrientation: allows you to decide if the view should rotate, and didRotateFromInterfaceOrientation: allows you to re-layout the view if necessary.
Please go through this link. In this they have explained clearly about design patterns.
http://www.raywenderlich.com/46988/ios-design-patterns
You might want to consider watching videos like the CS193p course from Stanford on iTunes U. They go through the most important parts of iOS development in deep, and give some source code.
As far as I can tell, there isn't a book or resource which deals with the sort of advanced gotchas and recipes that I was looking for. Loads of useful resources exist, but just not addressing the stuff I'm thinking about.
I'm brand new to iphone dev, but am familiar with the MVC pattern. Can anyone please explain why the GLPaint sample class PaintingView.m (the View) actually gets the data required from disk to write the "Shake Me!" text? The Data is the Model and should be read from the disk by the controller and passed to the View to render IMO. Correct?
Also, the Controller is adding UI controls to the view (color palette segmented control) - shouldn't the view be drawing this stuff?
Is this a bad example Apple have provided?
Thanks.
It's a good example of how to use OpenGL, but it's a poor example of MVC. I imagine that since MVC wasn't the focus of this example, it wasn't really written with it in mind.
At the end of the day, if the example works and shows you how to use the thing it's being an example of, then it's done its job.
I'm sure there are other examples of MVC out there from Apple that are done properly.
Thanks, I think it's a bit of a hack, but:
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW8
Combining Roles
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.