iPhone Delegates And Making 2 Instantiated Objects Talk To One Another - iphone

I have had about 6 hours trying to work out custom application delegates. even following tutorials i end up with errors!
I need a simple way of allowing one object to talk to another.
I have a root view. then another view which then pushes onto the stack with a list of options. then another view showing the relevant options based on the previous selection.
So basically 3 views, and i need view 3 to pass data back to view 1 when i popBackToRootViewController.... This is becoming a huge headache, for something that in theory should be so simple. I have previously just thrown data into nsuserdefaults but using protocols in the way apple suggest to do it.
Please can someone help me understand :)

There a different ways to solve that problem. First of all, you could pass the first View over and over to the View you are making changes on and then call a method of view 1. I won't recommend that.
Another, much easier way is to use Notifications. Just register your first View in the notification center [[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(somethingChanged) name:#"aStringWichIsUniqeForCallingSomethingChanged" object:nil];. You have to provide and implement a callback method (somethingChanged in my case). In your subwiew where the things happen, you have to post a notification by doing [[NSNotificationCenter defaultCenter] postNotificationName:#"aStringWichIsUniqeForCallingSomethingChanged" object:nil];. And don't forget to remove the view from the notificationcenter if they are not needed anymore!
[[NSNotificationCenter defaultCenter] removeObserver:self];
A third possibility is to use a singelton (like the app delegate) which contains all views that should communicate. Simple make all views as ivars & properties for them in this singleton and implement in each of them methods which should be called if something changes. Then call [[singelton sharedInstance] view1] somethingChanged].
If i say View, i mean viewController, but i'm to lazy to write that. ;)
Hope, that helps!

Protocols and delegation formalize a concept which works even if you don't follow the formal rules: It's about declaring a way for objects to talk to each other about the same thing, especially in those cases where you either don't have or don't want control about one of the objects, or in cases where things get complex and you want everything nice and tidy so it's easier to reuse the code.
In those cases however where a rather small, well known set of information is to be passed back and forth between two (or more) well known objects which are unlikely to be reused, informality is quite ok.
This means you could:
provide the sending object with a property of the type of the receiving object
implement a method in the receiving object which will take the information to be sent as an argument
at some point, for example in your case when the root controller pushes the child which becomes the sending object, the receiving object will set itself as the value of the sending object
if the sending object has information to send, it uses the reference to the receiving object to send it a message calling the earlier mentioned method, passing the information as an argument
As I mentioned before, this makes sense for glue code. You shouldn't be doing it this way though, if:
you're working in a team and you're working on one object and a teammate is working on the other
it's obvious you may be able to use the same functionality in a future project. In this case, think about having an intermediate subclass between your original superclass and your app-specific subclass, one that encapsulates the core functionality and offers a formal protocol to interface with it
the exchange of information involves objects of different classes within the same app
the exchange of information itself is rather complex and one (or two) glue methods wouldn't cover it

Related

Understanding the MVC design pattern in Cocoa Touch

Usually I just put together an app in any random way, as long as it works, but this means I don't pay any attention to any design patterns. My application currently makes extensive use of global variables (I carry an instance of my AppDelegate in every view controller to access properties I declared in my AppDelegate.h). Although it does what I want it to do, I've read this is not a good design practice.
So I want to start making my code "legit". However, I can't imagine my app right now without global variables. They are so important to the well-being of the app, but this must mean I'm doing something wrong, right? I just can't imagine how else I'd do some things. Take for example this:
You have two view controllers here, a SideViewController and a MainViewController. Using global variables, such as say if the entire application had one shared instance of SideViewController and MainViewController (appDelegate.sideViewController and appDelegate.mainViewController), I can easily communicate between the two view controllers, so that if I press "News Feed" in my SideViewController, I can tell my MainViewController to reload it's view.
I can't imagine, however, how this would be done if these were not global variables? If an event occurs in my SideViewController, how would I notify my MainViewController, in a way that is in accordance with design standards?
I can't imagine, however, how this would be done if these were not
global variables? If an event occurs in my SideViewController, how
would I notify my MainViewController, in a way that is in accordance
with design standards?
The same way you do it now, except that the SideViewController gets its reference to the MainViewController from a different place.
How are these two view controllers created? It's likely that it happens in one of two ways:
One of the objects creates the other. In this case, maybe the MainViewController creates the SideViewController.
Some other object, such as the app delegate or another view controller, creates them both.
In the first case, the MainViewController has a reference to the SideViewController as soon as it creates it. It can store that reference in one of its own instance variables, so that it can always send messages to the SideViewController that it created. Similarly, the MainViewController can give the SideViewController a reference to itself (that is, to the MainViewController), and the SideViewController can store that and use it in the future to talk to its MainViewController.
The second case is similar -- if the app delegate (or some other object) creates both MainViewController and SideViewController, that object knows about both objects and can configure each with a reference to the other.
In both cases, the objects in question are able to communicate with each other just as easily as they ever did and there's no need for a global variable.
What I've explained above is perhaps the simplest way to accomplish what you asked for -- communication between two objects. There are a number of patterns that can be used to refine the relationship between those objects to make your code even better:
delegation: Give SideViewController a delegate property, and define some protocol that establishes what SideViewController expects of its delegate. Implement that protocol in MainViewController. Make your MainViewController instance the SideViewController's delegate. SideViewController doesn't need to know exactly what type its delegate is -- it only cares that it's delegate implements the required protocol. This makes it easy to use SideViewController with something other than MainViewController if that opportunity arises, or to use it in a different project.
notifications: SideViewController may not even need a delegate -- it can simply broadcast notifications about certain events to any object that happens to be listening. This is particularly effective if more than one object might need to know about something that happens in SideViewController, or if the objects that care about SideViewController's actions might change.
MVC: Instead of telling MainViewController that something has changed, SideViewController just changes the data in the model. Whenever the MainViewController's view appears (or any other view controller's view, for that matter), the controller reads the data from the model and redisplays itself.
If you're interested, you might want to pick up a copy of Erik Buck's Cocoa Design Patterns, which explains these patterns and many others in great detail. Don't feel like you have to learn it all at once, or that it's all too much trouble. Learn a little bit at a time and see how it improves (or doesn't) your projects.

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.

Is this a bad idea?

I've been working on this problem for two days now. I'm working on an iPhone app that, at the moment, has "dual layer" view (see picture.) The semi-transparent orange panel covering the left third of the screen was created by simply resizing the sub-view (in IB) to take up less than half the screen so that, when that view loads, the original view is still exposed on the right. This would allow the left view to be a "menu view" allowing a user to select what he or she would like to appear in the main view window (which is actually a UIWebView...see screen shot.)
----- Click Here For Screen Shot-----
If I'm going to keep this setup (assuming it's not a structural sin), the left-view clearly needs a way to communicate with the main view. Can I invoke methods in the main-wiew ".m" file (WebViewController.m) like viewDidLoad and others from the "ETG" button on the orange subview? Or is this just a really bad idea? And if this isn't a bad idea or a sin against iPhone structure, how would you implement it? I'll thank you in advance for any helpful thoughts or suggestions you might have. Thanks!
If you're following the model-view-controller pattern, which you generally should, then your view should send messages to the controller or modify the model, not another view. Although it really depends on what you're doing. In your case you are using the panel as a control, so you should implement in a fashion that makes it independent of other views.
Usually the only time you have views directly manipulate other views is in layout, and that is normally in a top-down fashion.
Again, these are general rules and there are always exceptions.
What you are describing doesn't seem insane, but they way you go about talking to the main view might need a little work.
It seems like what you want to do is have the overlay view have a delegate that it can send messages to. Does that seem like it would work for you?
Umm, is the web view the main view?
Either way, I'd do this:
One view controller that contains two main areas. One is your UIWebView, and another is your layover. If you do this in Interface Builder, put the Layover on top of the UIWebView.
All you have to do is animate it in and out based on certain input. A bad idea is to say "hide menu" and make the UIWebView take up all the space, so you can't get it back.
Then use use one view controller for both.
The recommended method of communicating between view controllers, if that's subviewed, is to create properties in the view controller that you can pass. Eg: the web view needs to tell the main view what site it's on. So put an NSString in your main controller as a property, then pass it the string on viewWillDisappear or whatever that name is.
(Or, use viewWillAppear on the top level and have it grab that property from the 2nd view).
Essentially it's just a branching tree, and you have to pass data up one node to reach the others.
You "can" use the application's delegate itself/(the application) and from anywhere, call [UIApplication sharedApplication].property (after creating a property), and use it as a global, but that's not considered reusable code. Since you're used to basic, it might work for you.
Finally, C++ globals do work, and there are many examples on the web for using globals in an iPhone program with externs. (even less recommended).
Now, it sounds like you need to read the Views Programming Guide, even though it has severe grammar issues in areas (they may have corrected the homonyms in the 3rd paragraph of the intro by now, but other areas are totally confusing because of that), to get an understanding of how views respond to input, and what happens when input is ignored and bubbles up the tree. (that's basically what it does, lol... but layers and views have intricacies and it's good to understand them and how they function together).
No, it's not a bad idea. But without understanding layers, view animation, and design maybe it is, until you do.
NazCode
If I understand what you're trying to do, one approach is to use notifications. This way none of the objects involved need to have references to one another. Before I learned this approach, I had several awkward cases where I seemed to be working much too hard just to get two objects to talk to one another.
In your case, your orange layer can post notifications and the controller for the UIWebView can listen for them.
So when you tap the button in the orange layer, do something like this:
[[NSNotificationCenter defaultCenter] postNotificationName:#"etgTapped" object:self];
And in controller that looks after the webview add something like this to your viewDidLoad method:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(etgTapped:) name: #"etgTappe" object:nil];
And then create an etgTapped: (NSNotifaction*) notification method in that class.
Finally, in viewDidUnload de-register with the notification centre:
[[NSNotificationCenter defaultCenter] removeObserver:self];

Can someone please explain delegates in objective-c?

I have been using Objective-C for a while and pretty much understand most of its features. However, the concept of delegates eludes me. Can someone please give a succinct and easy to comprehend explanation of what delegates are, how they are used in the iPhone SDK, and how I can best make use of them in my own code?
Thank you!
There are a couple main reasons to use delegates in Objective-C, which are subtly different:
Enhancing the base functionality of a framework class. For example, a UITableView is pretty boring on its own, so you can give it a delegate to handle the interesting bits (creating table cells, adding text to section headers, what have you). This way, UITableView never changes, but different table views can look and act very differently.
Communicating to parent objects in your dependency hierarchy. For example, you may have a view with a button that the user may push to do something that affects other views. The view will have to send a message to its parent view, or perhaps the view controller, so that it can create or destroy or modify other views. To do this you'd pass the parent object into your view, most likely through a protocol, as a weak reference (in Objective-C, an assign property). The view could then send any message declared in the protocol to the parent, or delegate, object.
This approach need not involve views. For example NSURLConnection passes event back to its delegate, which may be the object that created it, using this mechanism.
Essentially, all a delegate is, is an object that accepts feedback from another object. Put simply, when stuff happens to an object, it tells its delegate (assuming it has one).
For instance, lets say I have a UIViewController with a UITextView placed in the middle of the view. I set up my UIViewController to be the delegate of the UITextView. Then, when certain actions are performed on the text view (begin editing, text changes, end editing, etc), it tells it's delegate so it can do whatever logic it needs to do, like spell checking every time characters change, or dismissing the keyboard when it receives a return key press.
Delegate methods perform a similar function to callback functions in C.
Hope that makes sense :)
Best and simple concept I got from a Lynda.com Tutorial was: When you set a Delegate it means you have been given work to do. So, if you want to use methods that are written in a protocol method, you must implement them by searching in the Delegate Class Reference and using them. I hope it helped.
By the way, Delegates are excellents. They are your friends. They have been made to make your life as a programmer much easier.

NSNotification vs. Delegate Protocols?

I have an iPhone application which basically is getting information from an API (in XML, but maybe JSON eventually). The result objects are typically displayed in view controllers (tables mainly).
Here is the architecture right now.
I have NSOperation classes which fetch the different objects from the remote server. Each of these NSOperation classes, will take a custom delegate method which will fire back the resulting objects as they are parsed, and then finally a method when no more results are available. So, the protocol for the delegates will be something like:
(void) ObjectTypeResult:(ObjectType *)result;
(void) ObjectTypeNoMoreResults;
I think the solution works well, but I do end up with a bunch of delegate protocols around and then my view controllers have to implement all these delegate methods. I don't think its that bad, but I'm always on the lookout for a better design.
So, I'm thinking about using NSNotifications to remove the use of the delegates. I could include the object in the userInfo part of the notification and just post objects as received, and then a final event when no more are available. Then I could just have one method in each view controller to receive all the data, even when using multiple objects in one controller.†
So, can someone share with me some pros/cons of each approach. Should I consider refactoring my code to use Events rather then the delegates? Is one better then the other in certain situations? In my scenario I'm really not looking to receive notifications in multiple places, so maybe the protocol based delegates are the way to go.
Thanks!
Actually, your design sounds sound. The clear Cocoa approach is using delegates, and is much preferred to throwing objects around. Also, defining your protocols this way makes your code very explicit and easy to understand. All in all: keep up the good work