3

I'm having a problem fetching data from a web service in my iOS application. I have an NSObject class called LoginService. LoginService's loginWithUsername method is called from the ViewController when a user clicks Login.

In my LoginService, I created a delegate called LoginServiceDelegate. Here are the codes for that in LoginService.h:

//Creating 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 creation 

Implemented in LoginService.m:

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

Now my LoginService is also a delegate of NSURLConnection. When the delegate method connectionDidFinishLoading has been called, the data fetched is then turned into NSDictionary using JSON and passed to loginResult. It works fine for LoginService, the data fetched is being logged.

Now my problem is that I'm trying to set for example, the value of fetched data to a label under my Login button from the ViewController.m. This is just to try if I can successfully fetch a data via LoginService delegate. The problem is, I can't. ViewController has already been made a delegate of LoginService. I tried it both in the viewDidLoad method and in the loginWithUserName method, which is what is called when the login button is pressed.

I have this code in my viewDidLoad method in ViewController.m:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    LoginService *ls = [[LoginService alloc]init];
    ls.delegate=self;
    [ls loginResult];

}

And at first, I tried setting a label's text to the login result, but since I was failing, I have this code just to see if the LoginService delegate method ever gets called in the ViewController.m:

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

This might be a very basic problem, but I'm very new to iOS programming and it is confusing me big time. I really hope someone can help me.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
christianleroy
  • 1,084
  • 5
  • 25
  • 39
  • Hey @Rob. I'm not too familiar with your terminologies haha. Sorry, newbie here, but I'll learn, promise. Anyway, the network interaction has been made if you mean if I was calling or fetching a data from the website, I just omitted that since it's not what my question was about. I'll check on your other observations and I'll update my program. Thanks. – christianleroy Nov 08 '13 at 17:04
  • If you want to discuss these unrelated observations, we should move it to chat: http://chat.stackoverflow.com/rooms/40842/custom-delegate-method-not-called-in-ios – Rob Nov 08 '13 at 17:43
  • As an aside, the recommended way to declare delegate properties is weak or assign, not strong (to avoid retain cycles). See http://stackoverflow.com/questions/7753841/recommended-way-to-declare-delegate-properties-with-arc for example. – Marco Nov 08 '13 at 20:57
  • You set up your delegate with (nonatomic, strong). you should always declare it as weak, otherwise it will hold the object which registered on it and you will get problems with the retain cycle – Alex Cio Jun 19 '15 at 12:16

1 Answers1

8

I think you are missing something. You declarations are perfect, but you calls are incorrect. It should be as follow..

ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    LoginService *ls = [[LoginService alloc]init];
    ls.delegate=self;
    [ls login];

}

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

LoginService

//You are missing this part
-(void)login{

    if([self.delegate respondsToSelector:@selector(loginResult:)]){
        [self.delegate loginResult:YOUR_RESULT_DICTIONARY]
    }

}

Explanation

Its like you are forwarding message to the class where you have set your delegates methods, for some action has happened, in you case, you are logging in from LoginService class, which handles all your login/api connections, and after login you want to send message to ViewController to which you have set your delegates method, and I am ensuring that where you have set delegate contains that method for no crash..

I hope it helps.

iphonic
  • 12,615
  • 7
  • 60
  • 107