I've been following this example to help me build a delegate but unfortunately I've missed something so it is not working for me. How do I set up a simple delegate to communicate between two view controllers?
My code looks like this:
// HintsViewController.h
#import <UIKit/UIKit.h>
#protocol HintDelegateProtocol;
#interface HintsViewController : UIViewController
#property (weak, nonatomic) id<HintDelegateProtocol> hintDelegate;
-(IBAction)showFirstLetter:(id)sender
-(IBAction)showHint:(id)sender;
-(IBAction)showAnswer:(id)sender;
#end
#protocol HintDelegateProtocol <NSObject>
-(void)HintsViewController:(HintsViewController*)hintsViewController
showFirstLetter:(NSString*)firstLetter;
-(void)HintsViewController:(HintsViewController*)hintsViewController
showHint:(NSString*)hint;
-(void)HintsViewController:(HintsViewController*)hintsViewController
showAnswer:(NSString*)answer;
#end
//
// HintsViewController.m
#import "HintsViewController.h"
#implementation HintsViewController
#pragma mark -
#pragma mark IBActions
/* As per a suggestion below I changed the code here /*
- (IBAction)showHint:(id)sender
{
[self.hintDelegate HintsViewController:self showHint:#"Hint"];
}
- (IBAction)showFirstLetter:(id)sender
{
[self.hintDelegate HintsViewController:self showFirstLetter:#"FirstLetter"];
}
- (IBAction)showAnswer:(id)sender
{
[self.hintDelegate HintsViewController:self showAnswer:#"Answer"];
}
#end
And then in the a Controller class I have the following:
//
// GameLogicController.h
#import "HintsViewController.h"
#interface GameLogicController : NSObject < HintDelegateProtocol>
#end
And in the implementation I have the following:
// GameLogicController.m
-(void) nextRiddle
{
HintsViewController *hintsViewController = [[HintsViewController alloc] init];
hintsViewController.hintDelegate = self;
}
#pragma mark -
#pragma mark HintsFunctionality
-(void)HintsViewController:(HintsViewController*)hintsViewController
showFirstLetter:(NSString*)firstLetter
{
NSLog(#"Show First Letter called");
}
-(void)HintsViewController:(HintsViewController*)hintsViewController
showHint:(NSString*)hint
{
NSLog(#"show Hint called");
}
-(void)HintsViewController:(HintsViewController*)hintsViewController
showAnswer:(NSString*)answer
{
NSLog(#"Show answer called");
}
Using breakpoints I can see that the IBActions in the HintsViewController are being called, but putting a breakpoint in any of the delegate methods in the gameLogicController are never hit. So I have missed an important step in setting up the connection between the GameLogicController and the HintsViewController. Can anyone help me spot it?
Say you have two files: one is your ViewController, and other is your ConnectionManager Class.
Declare protocol and its methods in your ConnectionManager class, and define your protocol methods in the ViewController class. By setting the delegate of your ConnectionManager class in ViewController Class, you can call your Protocol method.
#protocol ConnManagerDelegate<NSObject>
- (void)didReceiveData:(NSDictionary *)data;
- (void)didFailWithError:(NSError*)error;
#end
#interface ConnectionManager : NSObject<NSURLConnectionDelegate>
#property(nonatomic,assign)id< ConnManagerDelegate > delegate;
And elseswhere in the same file .m, when your response comes just call
[Self.delegate didReceiveData:mDict];
In the ViewController file after you alloc init ConnectionManager class, set its delegate to self and define the protocol methods. It is these methods you will have your response from ConnectionManager class.
This is all Protocol Delegation pattern
Related
I'm trying to call a delegate method but isn't working. Where is my mistake?
Here is the class where i have declared #protocol, delegate and the method:
#import "EEBaseVC.h"
#protocol EEInterstitialScreenDelegete;
#interface EEInterstitialScreen : EEBaseVC
#property(nonatomic,strong) id <EEInterstitialScreenDelegete> delegete;
#end
#protocol EEInterstitialScreenDelegete <NSObject>
-(void)interstitialScreenUpdateInfo:(EEInterstitialScreen *)interstitialscreen;
#end
And this is the declaration of the delegate method in another ViewController:
#pragma mark - EEInterstitialScreenDelegate
-(void)interstitialScreenUpdateInfo:(EEInterstitialScreen *)interstitialscreen
{
NSLog("hello");
}
I have to do some stuff to call this method in the previous view controller. But the if condition is not satisfied:
if (_delegete && [_delegete respondsToSelector:#selector(interstitialScreenUpdateInfo:)] ) {
[_delegete interstitialScreenUpdateInfo:self];
}
AnotherViewController * obj = [AnotherViewController alloc]init];
obj.delegate =self;
[self.navigationController pushViewController:obj];
Following is my code, there is no error but selector is not responding.
Code in ExampleTableviewSubProductDetail.h
#protocol EnterAmountDelegate <NSObject>
-(void)titlechange:(NSInteger)amount;
#end
#class ASIFormDataRequest;
#interface ExampleTableviewSubProductDetail : UIViewController<UIScrollViewDelegate>
{
}
#property (nonatomic, strong) id <EnterAmountDelegate>delegate;
Code in ExampleTableviewSubProductDetail.m
#implementation ExampleTableviewSubProductDetail
#synthesize delegate;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if([delegate respondsToSelector:#selector(titlechange:)])
{
//send the delegate function with the amount entered by the user
[delegate titlechange:20];
}
code in HostProductdetailViewController.h
#import "ViewPagerController.h"
#import "ExampleTableviewSubProductDetail.h"
#interface HostProductdetailViewController : ViewPagerController <ViewPagerDataSource, ViewPagerDelegate, EnterAmountDelegate>
{
}
code in HostProductdetailViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.dataSource = self;
self.delegate = self;
}
-(void)titlechange:(NSInteger)amount
{
NSLog(#"sdfsf");
}
In the viewwillapper following Line always return false
if([delegate respondsToSelector:#selector(titlechange:)])
Please let me know if i am missing anything.
Thanks
When pushing from HostProductdetailViewController to ExampleTableviewSubProductDetail you need to set the exampleTableviewSubProductDetail.delegate = self
As I see some other potentially dangerous things in your code try checking this example. It consists of 2 simple classes which are connected via delegate. Watch out for strong references on delegates as this code of yours will produce a retain cycle and cause a memory leak.
Protocol:
// defining a custom protocol
#protocol PingProtocol <NSObject>
- (void)didPing;
#end
Ping class:
//
// This class will be able to send notifications via delegate for the protocol PingProtocol
// Any object that implements PingProtocol will be able to assign itself to the delegate property and will be notified to all protocol methods
//
#interface PingClass : NSObject
// The listener object that implements PingProtocol
// Note this should be weak or there will a retain cycle
#property (nonatomic, weak) id<PingProtocol> delegate;
#end
#implementation PingClass
// Some event that happens will check if the delegate actually implements this method and call it.
// The respondsToSelector is not necessary in this case since the method is not optional though.
- (void)onEvent:(id)sender
{
if([self.delegate respondsToSelector:#selector(didPing)])
{
[self.delegate didPing];
}
}
// Will create a timer which will call onEvent: every second.
// Note there should be some way to invalidate the timer as this will cause a memory leak for the PingClass
- (void)startPing
{
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(onEvent:) userInfo:nil repeats:YES];
}
#end
Listener:
//
// This class will listen to PingProtocol methods.
// It will need to implement all non-optional methods defined by PingProtocol
//
#interface ListenerClass : NSObject<PingProtocol>
#property (nonatomic, strong) PingClass *someClass;
#end
#implementation ListenerClass
// will create a PingClass object and asign itself as a delegate to start listening to delegate methods
- (void)startListening
{
self.someClass = [[PingClass alloc] init];
self.someClass.delegate = self;
[self.someClass startPing];
}
// A protocol method
- (void)didPing
{
NSLog(#"Ping");
}
#end
Most likely you are missing self:
if([self.delegate respondsToSelector:#selector(titlechange:)])
You need to watch out for these things. The delegate in your case is closer to a function pointer then an actual object. You might also be able access it via _delegate as well.
I want to develop Custom Connection Class by which I can make API calls using it. I do not want to use any third party apis like afhttprequest or asihttp.
I want to develop my self this type of delegate. I have searched much things but I do not have much idea in CustomDelegates.
I wrote one example of custom delegate.
From ViewController.m we call method with two number for addition of another class (Addition class)
Addition class will add these two number and call delegate method so we can get answer of that two number in ViewController using custom delegate.
Addition.h
#import <Foundation/Foundation.h>
// write protocal for this class
// you can give any name of that protocol
#protocol AdditionDelgate <NSObject>
// delegate method of this delegate
-(void)answerOfTwoNumberAddition:(int)ans;
#end
#interface Addition : NSObject
{
}
// set property of that protocol, so using that we can call that protocol methods (i.e. ansOfYourAns)
#property (nonatomic, weak) id <AdditionDelgate> delegate;
-(void) addThisNumber:(int) firstNumber withSecondNumber:(int)secondNumber;
#end
Addition.m
#import "Addition.h"
#implementation Addition
-(void)addThisNumber:(int)firstNumber withSecondNumber:(int)secondNumber
{
int ans = firstNumber + secondNumber;
// call delegate method of "AdditionDelgate" protocol
// we already set delegate of viewController to this protocol
// so it will call viewController class "answerOfTwoNumberAddition" method
[self.delegate answerOfTwoNumberAddition:ans];
}
#end
ViewController.h
#import <UIKit/UIKit.h>
// import addition class
#import "Addition.h"
// set AdditionDelgate to class
#interface ViewController : UIViewController <AdditionDelgate>
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// creat object of class
Addition * additionObj = [[Addition alloc] init];
// set delegate as self to that so that methods delegate methods will call
additionObj.delegate = self;
// call method
[additionObj addThisNumber:2 withSecondNumber:3];
}
#pragma mark ----- Delegate method of Addition view ----
// this is delegate method of Addition class, it will call from "addThisNumber" method line of code
// ([self.delegate answerOfTwoNumberAddition:ans];)
-(void)answerOfTwoNumberAddition:(int)ans
{
NSLog(#"addition of two number is %d",ans);
}
#end
I hope it will help you
I have a protocol in one class:
#protocol DataStorageManager
- (void) saveFile;
#end
#interface DataManager : NSObject
{
id <DataStorageManager> delegate;
}
#property (nonatomic, assign) id<DataStorageManager> delegate;
//methods
#end
and its implementation:
#implementation DataManager
#synthesize delegate;
#end
and I have another class which is the adapter between the first and the third one:
#import "DataManager.h"
#import "DataPlistManager.h"
#interface DataAdapter : NSObject <DataStorageManager>
#property (nonatomic,strong) DataPlistManager *plistManager;
- (void) saveFile;
#end
and its implementation
#import "DataAdapter.h"
#implementation DataAdapter
-(id) initWithDataPlistManager:(DataPlistManager *) manager
{
self = [super init];
self.plistManager = manager;
return self;
}
- (void) saveFile
{
[self.plistManager savePlist];
}
#end
So when I in first method try to call my delegate method like this
[delegate saveFile];
Nothing happened. I don't understand what's wrong with the realization - it's a simple adapter pattern realization. So I need to use the delegate which will call the methods from the third class. Any help?
You are not setting the delegate property. You need to do this,
-(id) initWithDataPlistManager:(DataPlistManager *) manager
{
self = [super init];
self.plistManager = manager;
self.plistManager.delegate = self;
return self;
}
Also, in DataManager class remove the ivar declaration, just declaring property is sufficient, the ivar gets automatically created. Call the delegate method as below,
if([self.delegate respondsToSelector:#selector(saveFile)] {
[self.delegate saveFile];
}
Hope that helps!
In your case you forget to set your protocol delegate and also need to call protocol method
by self.delegate....
I just Give Basic Idea for how to Create Protocol
Also Read This Question
#DetailViewController.h
#import <UIKit/UIKit.h>
#protocol MasterDelegate <NSObject>
-(void) getButtonTitile:(NSString *)btnTitle;
#end
#interface DetailViewController : MasterViewController
#property (nonatomic, assign) id<MasterDelegate> customDelegate;
#DetailViewController.m
if([self.customDelegate respondsToSelector:#selector(getButtonTitile:)])
{
[self.customDelegate getButtonTitile:button.currentTitle];
}
#MasterViewController.m
create obj of DetailViewController
DetailViewController *obj = [[DetailViewController alloc] init];
obj.customDelegate = self;
[self.navigationController pushViewController:reportTypeVC animated:YES];
and add delegate method in MasterViewController.m for get button title.
#pragma mark -
#pragma mark - Custom Delegate Method
-(void) getButtonTitile:(NSString *)btnTitle;
{
NSLog(#"%#", btnTitle);
}
i have created a delegate for my project the code of my main view is
VedantViewController.h
#protocol VedantDelegate;
#interface VedantViewController : UIViewController
{
id <VedantDelegate> delegate;
}
//some other outlets
#property(nonatomic, assign) id <VedantDelegate> delegate;
#protocol VedantDelegate <NSObject>
- (void)display:(NSString *)JSONResponse;
#end
VedantViewController.m
#synthesize delegate;
[delegate display:jsonResponse];
SecondViewController.h
#interface SecondViewController : UIViewController<VedantDelegate>
- (void)display:(NSString *)JSONResponse;
SecondViewController.m
- (void)display:(NSString *)string
{
}
but this code is not working properly
when i debug the code using breakpoints the code reaches the
[delegate display:abc];
but it does not calls display function in SecondViewController.m file
i think my code is right but some mistake that i can't recognize
let me explain you the flow of my project this could be the problem
by default the VedantViewController view is launched
after that when the show button is click it calls the SecondViewController view in the view these is list button that calls the function in VedantViewController this function then calls the delegate method that is [delegate display:jsonResponse];
Thanks in Advance,
Arun.
The view controller which is confirming with the protocol, should have this line in the viewDidLoad or anywhere you are making the object of that viewController
Add this line in SecondViewController.m
VedantViewControllerObject.delegate = self;
#protocol VedantDelegate;
#interface VedantViewController : UIViewController{
id<VedantDelegate> delegate;
}
//some other outlets
#property(nonatomic,assign) id<VedantDelegate> delegate;
#protocol VedantDelegate <NSObject>
-(void)displayAccounts:(NSString *)JSONResponse;
-(void)display:(NSString *)JSONResponse;
#end
and also set delegate to object of VedantViewControllerObject class as self in SecondViewController class and the object of VedantViewControllerObject class should be initialized and allocated.
vedantViewControllerObject.delegate = self;
In your VedantViewController.h file you declared method as below
-(void)displayAccounts:(NSString *)JSONResponse;
But you are calling it [delegate display:jsonResponse];
You just try to call
[delegate displayAccounts:jsonResponse];
And in SecondViewController.m
(void)displayAccounts:(NSString *)string{
}
There are some issues in your code:
set the delegate in second view controller
vedViewObject.delegate = self;
You added displayAccounts method in delegate and calling display method, that can cause issues. If that methods are not implemented in the delegate class.
Add if condition like: if(delegate)[delegate displayAccounts:jsonResponse];