Reputation: 1104
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
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
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