christianleroy
christianleroy

Reputation: 1104

Custom Delegate Method Not Being Called in Objective-C

A user is prompted to login in ViewController. When the user clicks the login button, LoginService's method loginWithUsername:andWithPassword is called. This method uses NSURLConnection to fetch data from a web service and it authenticates the login credentials. It is an NSURLConnection delegate (now I know there is another NSURLConnection method that uses block, I just prefer this one because I understand this, at least haha).

I have set a protocol called LoginServiceProtocol, with a delegate method called loginResult which accepts an NSDictionary parameter loginData.

When the NSURLConnection delegate method connectionDidFinishLoading is called, I want to call the method loginResult and set its loginData parameter to the data fetched from the website.

My problem is, I can't seem to be able to call the loginResult method.

To set the protocol, I have this code for LoginService.h:

//To create a protocol
@protocol LoginServiceProtocol <NSObject>

-(void)loginResult:(NSDictionary*)loginData;

@end
//End of protocol creation

@interface LoginService : NSObject<NSURLConnectionDataDelegate>{
    NSMutableData* _responseData; //Response data catches the data received from the web api
    id<LoginServiceProtocol>delegate;
}

@property (nonatomic, assign) id <LoginServiceProtocol> delegate;

This is my LoginService.m implementation in the connectionDidFinishLoading NSURLConnection delegate method:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

NSDictionary *loginDict = [NSJSONSerialization JSONObjectWithData:_responseData
                                                     options:NSJSONReadingMutableContainers
                                                       error:nil];
[self loginResult:loginDict];
if([self.delegate respondsToSelector:@selector(loginResult:)]){
    [self.delegate loginResult:loginDict];
}
}

I wrote [self loginResult:loginDict] because without it, even the implementation of the delegate method in LoginService.m isn't called. Without it, the program does nothing. It does not show or do anything, even in my ViewController which is a delegate of LoginService. The implementation of loginResult in my LoginService.m is just an NSLog() checking if the method ever gets called.

I know I'm missing a very vital thing, but I can't find it out. I've been trying for quite a while now. Also, I get this warning:

Authosynthesized property 'delegate' will use synthesised instance variable '_delegate', not existing instance variable 'delegate'. 

I used the delegate in ViewController. Here is my ViewController.h:

#import <UIKit/UIKit.h>
#import "LoginService.h"

@interface ViewController : UIViewController<LoginServiceProtocol>{

}

@property (weak, nonatomic) IBOutlet UITextField *txtUsername;
@property (weak, nonatomic) IBOutlet UITextField *txtPassword;
@property (weak, nonatomic) IBOutlet UILabel *lblName;

- (IBAction)btnLogin:(id)sender;
- (IBAction)btnKeyResign:(id)sender;
- (void)loginResult:(NSDictionary *)loginData;

@end

And I used it in the ViewController.m like this, just to see if it gets called:

- (void)loginResult:(NSDictionary *)loginData{
    NSLog(@"Reached");
}

I assigned it in the viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self.navigationController setNavigationBarHidden:YES];

    LoginService* login = [[LoginService alloc]init];
    login.delegate = self;

}

Most recent LoginService.h

//Declaring custom delegate
@protocol LoginServiceProtocol <NSObject>

-(void)loginResult:(NSDictionary*)loginData;

@end


@interface LoginService : NSObject<NSURLConnectionDataDelegate>{
    NSMutableData* _responseData;
    id<LoginServiceProtocol>_delegate;
}
@property(nonatomic,strong)id<LoginServiceProtocol>delegate;
//End of custom delegate declaration

Most recent viewDidLoad implementation:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.navigationController setNavigationBarHidden:YES];
    self.ls.delegate=self; //Where ls is a strong reference of LoginService declared in .h

}

Upvotes: 0

Views: 2798

Answers (2)

jlehr
jlehr

Reputation: 15597

Your controller creates an instance of LoginService but doesn't take ownership of it, so the instance is deallocated at the end of viewDidLoad.

Upvotes: 0

Antonio MG
Antonio MG

Reputation: 20410

Remove:

id<LoginServiceProtocol>delegate;

from here:

@interface LoginService : NSObject<NSURLConnectionDataDelegate>{
    NSMutableData* _responseData; //Response data catches the data received from the web api
    id<LoginServiceProtocol>delegate;
}

Upvotes: 1

Related Questions