simple delegate usage help - MacRumors Forums
Register FAQ / Rules Forum Spy Search Today's Posts Mark Forums Read
Go Back   MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Feb 17, 2013, 05:42 PM   #1
dude1234
macrumors newbie
 
Join Date: Feb 2013
simple delegate usage help

hello there! i`m very confused about delegation..
i got the theorical idea of delegation but i just cant convert it to code..
i`ll explain:
lets say i`ve created a project in xcode and i have my viewcontroller.h\m and also my appdelegate.h\m now lets say i want to use:

Code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
this method is in the appdelegate.m file -for three days i`m trying to do this simple practice:

when didFinishLaunching occur set the IBOutlet Label (ivar of viewcontroller)
like this
Code:
label.text = "@dude";
code 4 better understanding:

AppDelegate.h

Code:
#import <UIKit/UIKit.h>
@class ViewController; 

@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
    ViewController *myvc;
}


@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) ViewController *myvc;

@end
AppDelegate.m

Code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.myvc = [[ViewController alloc] initWithNibName:@"view1" bundle:nil];
    
    
    self.myvc.label.text = @"dude";
    NSLog(@"hey from appdelegate wtf");
    NSLog(@"label = %@", self.myvc.label.text);
    
  
    // Override point for customization after application launch.
    return YES;
}

the code is not working because i dont know how to transfer the label.text change to the viewcontroller... i also noticed that in my AppDelegate.m file that when i tried to change the label text in my viewcontroller object like so:

Code:
self.myvc.label.text = @"dude";
it appeard as NULL in the later NSLog call!

i`m realy confused because i dont know how to use delegation in my app..
i know i can use Notification center for those things but i want to understand old fashion delegation usage.

i need help i`m frustrated... tnq!
dude1234 is offline   0 Reply With Quote
Old Feb 18, 2013, 08:22 AM   #2
ArtOfWarfare
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
I believe your method is missing a few lines. I've bolded what I think you're missing below:

Code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]] autorelease];
    self.myvc = [[ViewController alloc] initWithNibName:@"view1" bundle:nil];
    self.window.rootViewController = self.myvc;
    [self.window makeKeyAndVisible];
    
    self.myvc.label.text = @"dude";
    NSLog(@"hey from appdelegate wtf");
    NSLog(@"label = %@", self.myvc.label.text);
    
  
    // Override point for customization after application launch.
    return YES;
}
I got these lines just by looking at what the Single View template in Xcode contains... what template were you using?
__________________
Battery Status - On the Mac App Store
The only app that'll estimate when your wireless devices will need their batteries changed.
Including the ones paired with other Macs on your network.
ArtOfWarfare is offline   0 Reply With Quote
Old Feb 18, 2013, 08:33 AM   #3
dude1234
Thread Starter
macrumors newbie
 
Join Date: Feb 2013
single view app
and i use storyboard
dude1234 is offline   0 Reply With Quote
Old Feb 18, 2013, 09:11 AM   #4
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Your issue has little to do with delegation and much more to do with proper properties set up. The recommended approach to your issue would be to add a property to hold a string to your viewController. Your app delegate then sets that property at the appropriate time, like before you present your view controller. Then the viewController, in the viewDidLoad or viewWillAppear, uses the value of that property to set the text for your label. Make sense?
__________________
dejo is offline   0 Reply With Quote
Old Feb 18, 2013, 10:26 AM   #5
dude1234
Thread Starter
macrumors newbie
 
Join Date: Feb 2013
thats whay i did eventually, and it did work but i thought there is a better way to establish a connection between AppDelegate and Usercontroller.

i thought i could get the same thing thats i`m getting of using the NSNotificationCenter.. i thought i can do this:

put delegate in class (viewcontroller in my case) --> something happend (didfinishlaunching or smth) --> delegate inform my class (in runtime - object) --> class invoke some method.

i mean how else should it work ? i tried to set up a delegate in my viewcontroller earlier because it seems cleaner to put the appdelegate in viewcontroller instead of viewcontroller object in appdelegate, so i smth like this

Code:
AppDelegate *delegate = (AppDelegate*) [[UIApplication sharedapplication] delegate];
and thats how i reached the NSString i defined in AppDelegate:

Code:
self.label.text = delegate.myString;
it worked but whats the difference? why should i set a delegate rather then just an AppDelegate object? -

Code:
AppDelegate *notDelegate = [[AppDelegate alloc] init];
what does sharedapplication stand for?

lets say i did defined it as a delegate in ViewController - how can apply the AppDelegate methods on my ViewController?

in ViewController

Code:
[delegate didfinishlaunching:??];
that must not work, and i dont want to call the delegate method i want them to call me and tell me an event happend.

i am confused.

tnx for replying
dude1234 is offline   0 Reply With Quote
Old Feb 18, 2013, 11:36 AM   #6
ArtOfWarfare
macrumors 603
 
ArtOfWarfare's Avatar
 
Join Date: Nov 2007
Send a message via Skype™ to ArtOfWarfare
User Interface code should go in your view controller, not in your app delegate. If you had multiple screens in your application, you wouldn't want the app delegate to be controlling all of them... it results in messy code and it's a violation of basic OO principles. You'd have a separate view controller for each screen.

sharedApplication allows you to access your application itself, as opposed to a different application running on the device (there's currently no means of accessing any other applications, and I suspect there never will be a means of it, but Apple has made it easy for themselves to in the future have something like a UIApplication applicationWithBundleID: method in the future... and it's very possible they already use something like that in their private API.)
__________________
Battery Status - On the Mac App Store
The only app that'll estimate when your wireless devices will need their batteries changed.
Including the ones paired with other Macs on your network.
ArtOfWarfare is offline   0 Reply With Quote
Old Feb 18, 2013, 11:38 AM   #7
dude1234
Thread Starter
macrumors newbie
 
Join Date: Feb 2013
Quote:
Originally Posted by ArtOfWarfare View Post
User Interface code should go in your view controller, not in your app delegate. If you had multiple screens in your application, you wouldn't want the app delegate to be controlling all of them... it results in messy code and it's a violation of basic OO principles. You'd have a separate view controller for each screen.
yeah i know .. but how can i call method from appdelegate (see previous message)
tnx
dude1234 is offline   0 Reply With Quote
Old Feb 18, 2013, 12:40 PM   #8
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Quote:
Originally Posted by dude1234 View Post
...i dont want to call the delegate method i want them to call me and tell me an event happend.
Then, it seems to me, using NSNotifications is a better approach.
__________________
dejo is offline   0 Reply With Quote
Old Feb 18, 2013, 12:59 PM   #9
dude1234
Thread Starter
macrumors newbie
 
Join Date: Feb 2013
yeah but i dont know when should i use delegate ...
i thought all its job is to inform me when things happen, i mean whats the point if i should ask it all the time - didfinishlaunching?

if i want to know if button pressed by a delegate i need to call it the exact time i think the user pressed that button?! that does not make any sense
dude1234 is offline   0 Reply With Quote
Old Feb 18, 2013, 02:42 PM   #10
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Maybe we are getting ahead of ourselves here. I think maybe you should describe what your experience is with iOS / Objective-C / object-oriented programming. How comfortable are you with the fundamentals? What resources (please be specific) have you been using to educate yourself? What is your understanding of delegation? How would you say it differs from target-action pairs? Or notifications?
__________________
dejo is offline   0 Reply With Quote
Old Feb 19, 2013, 02:00 AM   #11
dude1234
Thread Starter
macrumors newbie
 
Join Date: Feb 2013
Quote:
Originally Posted by dejo View Post
Maybe we are getting ahead of ourselves here. I think maybe you should describe what your experience is with iOS / Objective-C / object-oriented programming. How comfortable are you with the fundamentals? What resources (please be specific) have you been using to educate yourself? What is your understanding of delegation? How would you say it differs from target-action pairs? Or notifications?

c++ school education (basics)
obj c self educated - read entire Programming In Objective c - Stephen G Kochan.

i use xcode 4.3.3

my understanding of delegation - an object that u connect to your object (class) and u tell him to do stuff for u - u can use the buit in delegate methods that come with the framework such as UIApplicatio and u can also create your own custom delegate with @protocol.

its name - delegate - describes its job the best : i delegate a job for my delegate and tell him what to do for a specific object.

i`ve read apple docs and many more explanation about the consept of delegation, but i cant seem to understand nothing besides the theory behind it, cant figure how to realy use it.

how i see delegation while comparing it to notification - while notification is a global way of communication, while u postNotification it goes into the NotificationCenter and everybody can recieve it (every observer). a delegate is more specific way of communication, i ask my delegate to tell me whenever an event happens.

an interesting thing is that i keep getting the idea that in objective c u ask the delegate if an event happend different than the delegate himself tells my object an event occur and automaticly the object execute a method. thats realy make unsense to me.

i if u think i dont understand the consept of delegation can u please explain it to me? as i said i have read apple docs and many other explanation - also the Stanford iphone course and couple of other vids. tnx alot i really appreciate it
dude1234 is offline   0 Reply With Quote
Old Feb 19, 2013, 07:25 PM   #12
Duncan C
macrumors 6502a
 
Duncan C's Avatar
 
Join Date: Jan 2008
Location: Northern Virginia
 
Quote:
Originally Posted by dude1234 View Post
hello there! i`m very confused about delegation..
i got the theorical idea of delegation but i just cant convert it to code..
i`ll explain:
lets say i`ve created a project in xcode and i have my viewcontroller.h\m and also my appdelegate.h\m now lets say i want to use:

Code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
this method is in the appdelegate.m file -for three days i`m trying to do this simple practice:

when didFinishLaunching occur set the IBOutlet Label (ivar of viewcontroller)
like this
Code:
label.text = "@dude";
code 4 better understanding:

AppDelegate.h

Code:
#import <UIKit/UIKit.h>
@class ViewController; 

@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
    ViewController *myvc;
}


@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) ViewController *myvc;

@end
AppDelegate.m

Code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.myvc = [[ViewController alloc] initWithNibName:@"view1" bundle:nil];
    
    
    self.myvc.label.text = @"dude";
    NSLog(@"hey from appdelegate wtf");
    NSLog(@"label = %@", self.myvc.label.text);
    
  
    // Override point for customization after application launch.
    return YES;
}

the code is not working because i dont know how to transfer the label.text change to the viewcontroller... i also noticed that in my AppDelegate.m file that when i tried to change the label text in my viewcontroller object like so:

Code:
self.myvc.label.text = @"dude";
it appeard as NULL in the later NSLog call!

i`m realy confused because i dont know how to use delegation in my app..
i know i can use Notification center for those things but i want to understand old fashion delegation usage.

i need help i`m frustrated... tnq!

I'll write another post about delegates, but first I need to talk about another design pattern, MVC (Model-View-Controller).

In MVC, the model stores the data. The view is the user interface, and the controller object is the broker, that takes information and presents it in the view.

When you have a MVC trio, the controller owns the view. nobody else should touch it. There are a lot of reasons for this. A big one is encapsulation. If only the view controller deals with the model, you can change the way the view controller presents it's data later, and no other part of your program has to change. As long as the public interface of your view controller stays the same, the internals, and the views it presents, can change completely.

When you try to have the app delegate modify your view controller's views directly, you are breaking the encapsulation of that view controller. Bad idea.

The technical reason it doesn't work is that until the view controller's views are displayed to the screen, they don't exist. They are only loaded when they are needed (the lazy loading design pattern.)

So, saying


Code:
    self.myvc = [[ViewController alloc] initWithNibName:@"view1" bundle:nil];
    self.myvc.label.text = @"dude";
After the first line, the view controller exists, but its views do not. So the second line is trying to send a message to self.myvc.label, but self.myvcl.label is nil. (The message you are sending is:
Code:
[self.myvc.label setText: @"dude"];
)

Duncan
__________________
Regards,
Duncan Champney, WareTo.
Check out our latest iOS app, Face Dancer, available for free on the App Store.
Duncan C is offline   0 Reply With Quote
Old Feb 19, 2013, 07:43 PM   #13
Duncan C
macrumors 6502a
 
Duncan C's Avatar
 
Join Date: Jan 2008
Location: Northern Virginia
 
Quote:
Originally Posted by dude1234 View Post
hello there! i`m very confused about delegation..
i got the theorical idea of delegation but i just cant convert it to code..

:snip:
Now, as to your questions about delegates. I'll quote the excellent "Cocoa Design Patterns" by Erik M. Buck and Donald A. Yactman:

Quote:
A delegate is an object that's given an opportunity to react to changes in another object or influence the behavior of another object. The basic idea is that two objects coordinate to solve a problem. One object is very general and intended for reuse in a wide variety of situations. It stores a reference to another object, its delegate, and sends message to the delegate at critical times. The message may just inform the delegate that something has happened, giving the delegate an opportunity to do extra processing, or the message may ask the delegate for critical information that will control what happens.
Your app delegate is an example of a system delegate. The system defined application object sends messages to an object you declare as the application's delegate, telling it about things that happen. ("You are finished launching", "you are about to go into the background", or "You just returned from the background")

Another example of system object that uses a delegate is a UITextField. A UITextField has a delegate property. The delegate needs to conform to the UITextFieldDelegate protocol. All methods in the UITextFieldDelegate protocol are optional. If you declare a delegate, you get notified as the user begins editing, ends editing, types characters, etc.

An example method from the protocol is textField:shouldChangeCharactersInRange:replacementString:

That method allows the text field to ask its delegate "The user is trying to change a range of characters to some new string. Should I allow it, or prevent it? By implementing that method, you an teach the text field complex new behaviors like filtering the input text and only allowing certain edits.

Another example where you might set up a delegate yourself is storyboards and segues.

View controller 1 might invoke a segue to create view controller 2 and display it. Say view controller 1 is a table view that displays a list of employees and view controller 2 is an editor screen that the user can use to make changes to the employee record.

You need a way for view controller 2 to send information back to view controller 1. However, you want view controller 2 to work with a variety of different source view controllers, not just your employee list view controller.

So, you define a protocol that lists the messages that view controller 2 can send to view controller 1.

Then, when view controller 1 invokes the segue to switch to view controller 2, it gets a prepareForSegue message that lets it pass data to view controller 2. In prepareForSegue, view controller 2 gets a pointer to the destination of the segue, view controller 2, and sets itself as the delegate for view controller 2.

View controller 2 doesn't care what kind of object its delegate is. All it cares is that it's delegate responds to a set of delegate messages.

I recently wrote a tutorial on using parent and child view controllers in iOS 6, using the new embed segue in iOS 6. When you set up an embed segue, it tells the system to load the embedded child view controller as a child.

In the tutorial, I define a parent view controller protocol and a child view controller protocol.

The child view controllers manage static table views, and send messages to the parent when the user selects list items or clicks buttons in the cells.

The child view controller protocol defines a single message that lets the parent tell the child to deselect its cells.

In my example of static child view controllers, you could use the setup I created to manage any lists of information that you wanted, and all the parent view controller needs to do is implement the parent delegate methods in order to get notified about the user's actions on the table view.

The parent view controller in the example project responds to cell selection and button tap messages by displaying text messages to the user.

You can download the project from github at this link:

Static table view sample project on github
__________________
Regards,
Duncan Champney, WareTo.
Check out our latest iOS app, Face Dancer, available for free on the App Store.

Last edited by Duncan C; Feb 19, 2013 at 07:53 PM.
Duncan C is offline   0 Reply With Quote
Old Feb 20, 2013, 03:32 PM   #14
dude1234
Thread Starter
macrumors newbie
 
Join Date: Feb 2013
Duncan, thank u! tnx alot!
i want to make sure i understand smth

vc1 = table view with lets say 4 employee

vc2 = view that presents: name, age

i set vc1 as a delegate for vc2 (vc1 adopts the protocol of vc2delegate)
and thats how i can tell vc2 which employee to present

why do i need vc2 to send info to vc1??


i have read

http://www.roostersoftstudios.com/20...s-development/

and also

http://css.dzone.com/articles/do-not...hcreating-your

along with your explanation made delegates much much clearer!
tnq so very much!
dude1234 is offline   0 Reply With Quote
Old Feb 20, 2013, 07:19 PM   #15
Duncan C
macrumors 6502a
 
Duncan C's Avatar
 
Join Date: Jan 2008
Location: Northern Virginia
 
Quote:
Originally Posted by dude1234 View Post
Duncan, thank u! tnx alot!
i want to make sure i understand smth

vc1 = table view with lets say 4 employee

vc2 = view that presents: name, age

i set vc1 as a delegate for vc2 (vc1 adopts the protocol of vc2delegate)
and thats how i can tell vc2 which employee to present

why do i need vc2 to send info to vc1??


i have read

http://www.roostersoftstudios.com/20...s-development/

and also

http://css.dzone.com/articles/do-not...hcreating-your

along with your explanation made delegates much much clearer!
tnq so very much!
In my sample project I am using static table views. Each table view is managed by its own view controller. The sample project has 2 view view controllers, each hosting a table view, that are contained in a parent view controller.

The table view has the parent view controller as a delegate. When the user selects a cell in one of the table views, it's view controller notifies the parent view controller that a cell was selected.

Download the project and run it. Nothing beats working code to explaining a point.

That's not the same thing as the master/detail design you are talking about.

In your design, lets say your detail view controller, VC2, allows you to edit the record, with save and discard buttons. Let's say it also has next and previous buttons, so you can page through the employees one at a time.

You might have your detail view controller send a message to its delegate, the master view controller, when the user commits changes, so it knows to update that entry in the employee table.
__________________
Regards,
Duncan Champney, WareTo.
Check out our latest iOS app, Face Dancer, available for free on the App Store.
Duncan C is offline   0 Reply With Quote
Old Feb 21, 2013, 09:01 AM   #16
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Quote:
Originally Posted by dude1234 View Post
vc1 = table view with lets say 4 employee

vc2 = view that presents: name, age

i set vc1 as a delegate for vc2 (vc1 adopts the protocol of vc2delegate)
and thats how i can tell vc2 which employee to present
No, delegation should not be used to have the delegate pass information to the delegator. That is the wrong direction of flow. In order for vc2 to know which employee to present, normally you would have a property for, say, an instance of the employee model object, in vc2, and then, before presenting vc2, vc1 would set that property to the employee of interest.

Quote:
why do i need vc2 to send info to vc1??
For example, in your case, you could use delegation to inform vc1 that vc2 has made changes to the employee object and that it might want to reload its table in order to reflect this change.

Another, very common, scenario is that Apple recommends that the presenter of a viewController be the one to dismiss it. So, vc2 would send a, say, didFinishPresenting: message to its delegate (vc1), which would then be responsible for calling dismissViewControllerAnimated:completion:, as well as anything else it would like to do in response.

Simple code example:
vc2
Code:
- (IBAction)saveButtonTapped:(id)sender
{
    ...
    [delegate didFinishPresenting:self.employee];
}
vc1
Code:
- (void)didFinishPresenting:(Employee *)presentedEmployee
{
    [self dismissViewControllerAnimated:YES completion:nil];
}
__________________
dejo is offline   0 Reply With Quote
Old Feb 21, 2013, 12:57 PM   #17
PhoneyDeveloper
macrumors 68030
 
PhoneyDeveloper's Avatar
 
Join Date: Sep 2008
Quote:
No, delegation should not be used to have the delegate pass information to the delegator.
The delegator can ask the delegate for both behavioral information and data. The UITableView dataSource and delegate protocols work like that. Also UITextField has several delegate methods that return BOOLs to indicate behavioral choices, although not really any to fetch data. It's OK for the delegator to ask questions of the delegate.

OP, learn to use UITableView and this will become more clear.
PhoneyDeveloper is offline   0 Reply With Quote
Old Feb 21, 2013, 02:48 PM   #18
Duncan C
macrumors 6502a
 
Duncan C's Avatar
 
Join Date: Jan 2008
Location: Northern Virginia
 
Quote:
Originally Posted by PhoneyDeveloper View Post
The delegator can ask the delegate for both behavioral information and data. The UITableView dataSource and delegate protocols work like that. Also UITextField has several delegate methods that return BOOLs to indicate behavioral choices, although not really any to fetch data. It's OK for the delegator to ask questions of the delegate.

OP, learn to use UITableView and this will become more clear.
You can certainly ask your delegate information.

However, the delegate should not as it's delegator for information. That was dejo's point.

Ok:
"Hey delegate, what color should I make this view?"

Not Ok:
Delegate: "Hey delegator, who cuts your hair?"
__________________
Regards,
Duncan Champney, WareTo.
Check out our latest iOS app, Face Dancer, available for free on the App Store.
Duncan C is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Simple question: turn by turn directions and data usage Loa iPhone 10 Aug 5, 2013 07:54 PM
iPhone: Get Tethering Data Usage in Settings>Usage>Cellular Usage? AlphaDogg Jailbreaks and iOS Hacks 1 Feb 16, 2013 10:14 PM
UIScrollView delegate methods not called. zaxonus iPhone/iPad Programming 1 Jan 4, 2013 12:38 AM
Setting A ViewController as another VIewcontrollers Delegate daproject85 iPhone/iPad Programming 3 Oct 3, 2012 05:53 AM
List of iOS Delegate Protocols rnls001 iPhone/iPad Programming 2 Aug 17, 2012 09:57 AM

Forum Jump

All times are GMT -5. The time now is 09:08 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC