I have two Classes - say Class1 and Class2
Class1 has button which when pressed does a push segue to Class2.
Also, when the button is pressed a network call is being done on another class.
Class1 code :
- (IBAction)sellPressed:(id)sender
{
SPNNetworkEngine *networkEngine = [[SPNNetworkEngine alloc] init];
networkEngine.delegate = self;
[networkEngine getFarePrice];
}
In Network class, I have :
In .h file
#protocol SPNNetworkEngineDelegate <NSObject>
- (void) farePriceReceivedWithDetails:(id) farePrice;
#end
#property (nonatomic, weak) id delegate;
- (void) getFarePrice;
In .m file
- (void) getFarePrice
{
...........
.......
//After all the operations, I delegate
if ([delegate respondsToSelector:#selector(farePriceReceivedWithDetails:)])
[delegate farePriceReceivedWithDetails:cost];
}
}
And in Class2 I have,
- (void)viewDidLoad
{
[super viewDidLoad];
SPNNetworkEngine *networkEngine = [[SPNNetworkEngine alloc] init];
networkEngine.delegate = self;
}
// Delegate method
- (void) farePriceReceivedWithDetails:(id)farePrice
{
NSLog(#"FarePrice %#", farePrice);
}
The delegate method in Class2 is never called. What have I done wrong here?
But when I write the delegate method -(void)farePriceReceivedWithDetails:(id)farePrice in Class1, its working fine.
Your Coding approch is wrong You alloc SPNNetworkEngine class in Your Class1 and set delegate of SPNNetworkEngine is self. so The delegate is fire in class1. But you want this method in class2 so you have to assign this delegate with class2 object.
Second point is you have to Change this line with this
#protocol SPNNetworkEngineDelegate <NSObject>
- (void) farePriceReceivedWithDetails:(id) farePrice;
#end
#property (nonatomic, strong) id <SPNNetworkEngineDelegate> delegate;
- (void) getFarePrice;
You should retain this object in Class1.h as instance variable. So that it will be alive till that class object exist. What you are doing currently is simply allocating it in a method. once the method executed & finished, it will be deallocated. So your delegate call back will not work.
So avoid this line
SPNNetworkEngine *networkEngine = [[SPNNetworkEngine alloc] init];
change the above code to like below
Declare in Class1
#property (nonatomic, strong) SPNNetworkEngine *networkEngine;
Then do
self.networkEngine = [[SPNNetworkEngine alloc] init];
In the Class1 you are calling to [networkEngine getTestPrice] and I think that mean the [networkEngine getFarePrice] function (because is where you call the delegate)
In Class2 you must call the same function: [networkEngine getTestPrice]
Have you added the SPNNetworkEngineDelegate to the list of delegates in the Class2.h?
i.e.
#interface Class2 : UIViewController <SPNNetworkEngineDelegate>
Related
So I am calling delegate function but some how its not getting called, I tried everything from all the other similar threads but nothing works. It looks all good but the method is still not called. here is my code below -
So i created protocol like this -
AuthViewController.h
#class AuthViewController;
#protocol AuthViewControllerDelegate <NSObject>
- (void)updateNavigation:(NSString*)pageType
message:(NSString*)message;
#end
created a property -
#property (nonatomic, weak)id delegate;
And called the function in AuthViewController.m -
[self.delegate updateNavigation:#"xx" message:#"xx"];
Then in other class -
AssociateViewController.h
#interface AssociateViewController : UIViewController <AuthViewControllerDelegate>
#property (nonatomic, strong)AuthViewController *vc;
#End
AssociateViewController.m
First set the delegate in a button action or viewWillAppear(I tried both)-
self.vc = [[AuthViewController alloc] init];
self.vc.delegate = self;
And the here is the method which is somehow never called :( -
- (void)updateNavigation:(NSString*)pageType
message:(NSString*)message;
{
//method to do
}
Any help would be much appreciated. Thanks!
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 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);
}
can't understand what's wrong in this case, so I cant use the delegate - there is an exception in self.plistManager.delegate = self; Property 'delegate' not found on object of type 'DataPlistManager *'
#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;
self.plistManager.delegate = self;
return self;
}
- (void) saveFile
{
[self.plistManager savePlist];
}
#end
Your DataPlistManager needs a property delegate:
#property (weak) id<DataStorageManager> delegate;
If you add #import "DataAdapter.h" in your "DataPlistManager.h" file then remove it and add it to "DataPlistManager.m" file, I don't know but some days ago i have same issue, and i solved it by using this trick :)
DataManager class contains delegate property so you should set your object as delegate of DataManager class and call method (send message) saveFile inside delegate class:
#implementation DataAdapter
- (void)someMethod) {
DataManager *dataManagerObject = [[DataManager alloc] init];
dataManagerObject.delegate = self;
}
#implementation DataManager
- (void)someDelegateMethod {
[self.delegate saveFile];
}
Are you sure you understand concept of delegation pattern?
https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/DelegatesandDataSources/DelegatesandDataSources.html
I am trying to pass some data back to my UIView, its abit of a complicated situation I will try to explain it.
I have my
mainViewController // request is made to RequestClass
requestClass // Request is sent off to DB for data, data is returned then passed to seriesDataClass
seriesDataClass // sorts the data and then sends back the needed info to mainViewController using protocol & delegates
This is what my code looks like for setting up the protocols and delegates
mainViewController.h
#import "SeriesDataClass.h"
#interface MatchingSeriesViewController : UIViewController <GetSeriesViewParsedData>
{
mainViewController.m
#import "SeriesDataClass.h"
// this is where I set up my protocols delegate.
- (void)viewDidLoad
{
//..
// get delegate ready
SeriesDataClass *seriesDataClass = [[SeriesDataClass alloc] init];
[seriesDataClass setDelegate:self];
//..
// pass data over to requestClass so you can get the info from the DB
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//..
[requestClass GetSeries:requestID];
//..
}
requestClass.m
// dose a bunch of stuff then calls seriesDataClass and passes all of its information over to it
//..
SeriesDataClass *seriesDataClass = [[SeriesDataClass alloc] init];
[seriesDataClass recivedData:uncompressedData];
//..
seriesDataClass.h
#import <Foundation/Foundation.h>
// This passes data back to the mainViewController
#protocol GetSeriesViewParsedData <NSObject>
- (void)sendGetSeriesArrays:(NSDictionary *)series LSeries:(NSDictionary *)lSeries;
#end
#interface SeriesDataClass : NSObject <NSXMLParserDelegate> {
//..
}
#property (assign, nonatomic) id <GetSeriesViewParsedData> delegate;
seriesDataClass.m
#implementation SeriesDataClass
#synthesize delegate;
// then in a method later on i call the delegate to pass the information back to mainViewController but this dosnt do anything atm.
//..
[self.delegate sendGetSeriesArrays:seriesDictionary LSeries:lSeriesDictionary];
//..
mainViewController.m
// then back in the mainViewController class I Have the method
- (void)sendGetSeriesArrays:(NSDictionary *)series LSeries:(NSDictionary *)lSeries {
// this method is never accessed
}
So my question is what am i missing in the set up of this protocol/delgate for it not to be working correctly?
I hope the structure of the question makes sense if you need any more information please let me know.
Your problem is that you are creating 2 instances of your SeriesDataClass, one in MainViewController, and another in RequestClass. So, the instance that calls the delegate method is not the same instance that the main view controller set itself as the delegate of. When you create an instance of RequestClass in MainViewController, you need to pass seriesDataClass (the instance you created) to a property in RequestClass, so that it will be working with the same instance.
You should create a property in MainViewController:
#property (strong,nonatomic) SeriesDataClass *seriesDataClass;
The viewDidLoad method should then look like this:
- (void)viewDidLoad {
self.seriesDataClass = [[SeriesDataClass alloc] init];
[self.seriesDataClass setDelegate:self];
}
Then in didSelectRowAtIndexPath, create your RequestClass instance, and pass it seriesDataClass:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
RequestClass *requestClass = [[RequestClass alloc] init];
requestClass.seriesDataInstance = self.seriesDataClass;
[requestClass GetSeries:requestID];
}
In the .h of RequestClass you need to have created that property:
#property (strong,nonatomic) SeriesDataClass *seriesDataInstance;
Then in RequestClass, this:
SeriesDataClass *seriesDataClass = [[SeriesDataClass alloc] init];
[seriesDataClass recivedData:uncompressedData];
should be replaced with just:
[self.seriesDataInstance recivedData:uncompressedData];
I've changed some of the capitalization, to reflect the way you should do it. Classes should start with capital letters, and instances and methods should start with lowercase ones.
Change this:
#import "SeriesDataClass.h"
// this is where I set up my protocols delegate.
- (void)viewDidLoad
{
//..
// get delegate ready
SeriesDataClass *seriesDataClass = [[GetSeriesResultItem alloc] init];
[seriesDataClass setDelegate:self];