Responsibilities of Delegates and Controllers in Cocoa Touch? - iphone

I'm new to development on the iPhone. Just about every sample project (as well as the default project templates) have one or more delegates and controllers. Can someone give me a breakdown of what the delegates are responsible for vs. what the controllers are supposed to do?

The simplest way I can think to differentiate the two are:
A delegate is a protocol (interface) that defines methods that an object implements in order to receive specific messages from other objects. Delegates objects are most often used to receive asynchronous callbacks such as user input, I/O.
A controller is an object that usually contains UI elements (views, controls, etc.) and data, and both receives and send messages to the various objects within it. In many cases, a controller is a delegate and can implement several delegate protocols to receive events from multiple objects.
Keep in mind that many UI elements and controls let you pass events back to the controller by linking them to an IBAction method in Interface Builder. This is very handy as it doesn't require extra code to implement delegates. However, some other APIs such as the ABPeoplePickerNavigationController or NSURLConnection have no visualization in Interface Builder and so must use delegates to handle their events.

A delegate is some object that implements a set of methods which either your application or the framework you link against depends on for functioning. It is a means of implementing a delegation based design pattern wherein the responsibility for performing an action is transferred from some root source to an interested third party. For instance, UIApplication has delegate methods that provide a third party with the ability to perform operations at certain times during the applications lifetime. It can be though of as a milestone in a timeline into which you can contribute to the story.
A controller is a totally different animal and is responsible for doing, well, the controlling. A ViewController is charged with managing views - for loading them into memory from disk when they are needed and unloading them when they are not. They transform content from some underlying model object into a form that is usable by your view objects, load content into your in-memory model from the disk or from the internet, and dump the contents back to disk when you save and/or quit.

Related

Need of Delegation in iPhone Development or Objective C

What is the need of delegation in iphone/ipad development or objective C?
I read so many articles on it. All were telling how to implement the concept, but no one was telling why we need to implement that, in which case we should implement it.
Suppose you want to implement Login functionality in your app ... now you won't show Login screen every time you run your app.. only when it is first started and you don't have a login and password...
So in this case..
Your app starts :
View 1 loads (default view )
You check no Login name is there..
You load a new view..(Login View ) .
User enter his details..you get your login and password...
now you want to go back to default view and load the main app with
the names the user entered in Login View....
Now you will use delegate to pass these information(login details) back to default View..so that it knows..its details. now there are many different ways to do these things...like notification and singleton classes.. but when you want to sent more than 3-4 sets of data.. it is best to use delegates
Think of all the components that iOS and Cocoa provide you with. TableViews, TextFields, PopOvers...etc.
When the developers wrote these components, they couldn't possibly know all the various implementations that us developers were going to create using these components. But we need somehow to communicate with them in a generic way.
These components use delegates. The delegate is an implementation independent way of describing some behaviour that your component can conform to.
When UITableView need to find out what is the height of the rows, the UITableView only needs to know about UITableViewDelegate. It doesn't need to know about MyTableViewController, JohnsTableViewController, BobsTableViewController... etc.
So the delegate is decoupling the component from the implementation and the type.
Decoupling is a good thing. It makes maintaing and changing code a lot easier, and makes code reusable.
Delegation is a simple and powerful pattern in which one object in a
program acts on behalf of, or in coordination with, another object.
The delegating object keeps a reference to the other object—the
delegate—and at the appropriate time sends a message to it. The
message informs the delegate of an event that the delegating object is
about to handle or has just handled. The delegate may respond to the
message by updating the appearance or state of itself or other objects
in the application, and in some cases it can return a value that
affects how an impending event is handled. The main value of
delegation is that it allows you to easily customize the behavior of
several objects in one central object.
SOURCE
Use a delegate if you want to talk to only one object. For example, a
tableView has a delegate - only one object should be responsible for
dealing with it.
Use notifications if you want to tell everyone that something has
happened. For example in low memory situations a notification is sent
telling your app that there has been a memory warning. Because lots of
objects in your app might want to lower their memory usage it's a
notification.
this was an answer posted to my question here
There are two key benefits of delegation: customizing objects without subclassing, and improving encapsulation.
Customization without subclassing is a benefit you get from many of the Cocoa and Cocoa-Touch APIs using the delegate pattern. If they didn't do so, you might have to subclass a UITableView every time you wanted to change its behavior by using different types of cells or a different data source. Instead, you just set the table view's delegate and data source to customize its behavior.
As for encapsulation, the delegate pattern helps you keep the different components of your code separate. For example, if your custom View needs to have some data, it would be bad practice to simply give it access to your Model, or even full access to your Controller. Instead, you'd probably set up some kind of delegate protocol for your View that your Controller would implement. That way your classes know no more about each other than they need to, so that changes in one part would be less likely to break others.

Quick overview of the structure if iPhone apps

Can someone give me a quick, one-to-few paragraph(s) overview of the structure of iPhone apps. I'm working my way through a book, but I can't really understand the purpose of App Delegates, MainWindow.xib vs. individual views' nib files, actions vs. outlets, etc.
I'm looking for a high-level description, because all I can find are really detailed accounts of this stuff.
You can find out more about Objective-C design patterns like delegation in Apple's documentation. Here's a quick overview of the things you mentioned:
Objects communicate with other options in various ways, one of which is delegation. An app delegate is an object that receives certain messages from the application.
XIB files contain a description of your user interface and connections. MainWindow.xib contains the UI information for your main window, but you should have individual XIB files for other view controllers for the sake of efficiency (you should load the XIBs lazily when the user tries to instantiate a certain kind of view controller, and cache the XIB to prevent reloading it; see UINib for detail).
Actions and outlets are ways of connecting code to UI elements in your XIB. An action is a message sent by a UI element to an object. For example, a button press can send an action to your view controller. An outlet would be a reference to that button.
For more about Objective-C in the context of iOS development, consult the documentation:
http://developer.apple.com/iphone/library/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/index.html
http://developer.apple.com/iphone/library/referencelibrary/GettingStarted/Creating_an_iPhone_App/index.html
The physical structure of an iPhone application consists of a directory that acts as a bundle for the main executable and all resources used (images, property lists, interface files, etc.).
When run, the executable first performs the main() function. That function either programmatically instantiates an application delegate or loads the main interface file (which specifies the application delegate). The application delegate acts in response to application-level events, such as termination or entering and exiting the background.
The construction of your interface can either occur programmatically or through the use of Interface Builder .xib files. If programmatically, your application delegate will construct the initial overall interface, then hand things off to individual view controllers to manage the display of specific views. If done via Interface Builder, you'll define interface files that compile into freeze-dried objects that are deserialized into your interface at runtime.
Overall, Cocoa applications tend to follow the Model-View-Controller design pattern, where these three areas of your application are separated in code. Views are generic reusable display elements, your model contains application data (often persisted using Core Data or SQLite), and your controllers provide the application-specific logic that glues everything together.

How does the Model talk to the View Controller?

Here is something I just can't get to work....I can make the view controller talk to my custom objects just fine....but how do I send messages to the View Controller from my objects?
A message from myViewController to myObject would look like
[myObject doSomething].
What would the opposite message look like? Does it even make sense to send a message the other way?
Greatly appreciate your help!
You could pass a controller to a model, but often you want models to not depend on views or controllers.
To avoid that, make a protocol that the model wants to talk to and have the view controller implement it and have the model take an instance of the protocol, not the view controller as a property.
I often use NSNotificationCenter to broadcast updates from model objects to interested controllers. For a more tightly bound interaction, consider making a delegate protocol for the model object.
A notification is mostly one way, although the listener could access the model object that sent the notification. There can be any number of interested parties, including none if controllers come and go but the model is persistent.
A delegate is two way, but there can only be one delegate at a time. Usually a delegate is expected to outlive the object it is a delegate to. A delegate might be good for a phase of a model object lifespan that requires extra user input.
Notifications and delegates can be used simultaneously. As with UIApplication, the delegate is usually called before the notification is sent.
Why would you want your model to actively talk to anything in the first place? View controllers are the active managers of the app flow, and initiate communications to the model, not the other way around.
Can you say a more specific example of a situation where you would actually need to do this?
Like you suspect yourself, most of the time it doesn't make sense to send messages “the other way.” But if you really need to do that, an appropriate way to broadcast information “out” from models is notifications. You can have your model send notifications, and view controllers or any other objects can subscribe to those notifications if they care, but there is no tight coupling from model to other app pieces.

How to organize delegate files

In cocoa-touch development...
Use AppDelegate for delegate classes
Create separate delegate class and locate in new .h/.m for each class need to use delegate
Use view controller classes(whenever such exist) to do that job for all
classes managed by this controller
What would you recommend?
Well it depends. The entire concept for delegate protocols exist so that you can have a lot of flexibility. Sometimes you take the simply default route but sometimes you need to be able to have a lot of different delegate classes.
(1) App delegate -- the app delegate should only be used for UIApplicationDelegateProtocol methods or delegates for actual properties of the delegate instance itself. In other words, if the app delegate doesn't directly deal with an instance e.g. the application object, then the app delegate should serve as the instance's delegate. Piling up extranous methods in the app delegate will muddle the app and make it snarlingly interconnected and difficult to debug and maintain.
(2) Wholly separate delegate classes are usually used when you have (A) a large number of delegate protocols to implement or (B) you have the same protocol to implement for multiple instances but require a different behavior for each object's delegate. E.g. you have several UITextFields each of which behave differently. You create as separate delegate class for each so that each text field has it's own custom implementation of the delegate protocol's methods.
(3) Using the controller for delegates is the easiest, most logical and most modular way to go in the majority of cases. In many cases such as UI elements the delegate methods need an awareness of other UI elements which the controller can provide.
In sum, never do (1) as a general parking place for any random delegate methods and default to (3) in the majority of cases.

Design pattern for Core Data iPhone App

Im building an app that will use a Core Data model. I pretty new at Objective C and my usual design patterns does not really apply on Core Data and Objective C, at least I can't seem to find examples that confirms they will.
I have been through the Apple Developer examples and different sources on the intertubes.
It seems that to leverage Core Data I need to pass the managedObjectContext to each of my viewControllers, have the viewController implement the NSFetchedResultsControllerDelegate and then implement each of the methods for doing a fetch and subsequently implement
NSFetchedResultsChangeInsert
NSFetchedResultsChangeDelete
NSFetchedResultsChangeMove
NSFetchedResultsChangeUpdate
This adds approximately 100+ lines of code in each viewController and it is 90% the same code I write again and again. Plus I have to pass everything around and keep track of it's memory footprint.
In other languages I would build a singleton model of a few classes that held methods for maintaining and delivering data upon request, available from anywhere. It seems I can't take that approach in Objective C. If I where to build a static Class that took a managedObjectContext and returned me what I needed, I would still have to pass the managedObjectContext around to every view and it wouldn't be asynchronously like when I implement delegate methods that just gets called when a result is ready.
I hope this makes sense and that someone can either confirm that there is no other reasonable way to do it or help point me in a direction for wrapping this up in a good way.
Thanks:)
Core Data is not nearly as complicated as you describe.
Generally, an iPhone app has a "main" managed object context, which is generally owned by the app delegate. So long as you can get the app delegate (hint: [[UIApplication sharedApplication] delegate]) you have access to the managed object context. I like to define a static global variable to hold a reference to my app delegate to make life easier.
There's generally a one-to-one correspondence between NSFetchedResultsController instances and UITableView instances. Aside from populating table views, it's exceedingly rare that you would need an NSFetchedResultsController. If you have a number of similar views (e.g. a tab bar that lets you view the same data in different ways a la the iPod app), it would behoove you to create a single base class that configures the NSFetchedResultsController and derive your specific view controllers from that.
Now, when you create view controllers to edit an object, it's generally a good idea to do that in a separate managed object context. If the user cancels, you just discard the context and the changes go away. Again, you don't really need an NSFetchedResultsController for this because these views are only concerned with a single object.
When you're done editing, you save: the managed object context. The objects that manage your other managed object contexts should implement the NSFetchedResultsControllerDelegate methods to keep the table view in sync. Again, this can be implemented in a base class so you can generalize this functionality for related view controllers.
Do you absolutely have to use a CoreData model, or would something using a NSCoder (NSArchiver, NSKeyedArchiver, etc) work? I've found that CoreData is overkill for most applications.
Also, could you clarify why you can't take an approach using singletons? I've used singleton factories in a number of applications without issues. It's fairly easy to define class-level methods that operate on a shared (singleton) instance.