views:

250

answers:

2

Currently I'm working on an iPhone app that asks the user for login information, verifies this information and presents the user with a table view of their information.

On launch the application delegate launches an empty table view along with the modal view to ask for login credentials. The login credentials consist of a standard username/password field and a button to send the information to a server.

When the users credentials have been verified I want to send a message to the TableView beneath the LoginView that says 'hey, the users credentials have been verified, could you please gather all the data for this user and dismiss the view controller.' I looked at a few tutorials from Apple, specifically the Recipe Table View example, (uses delegation to add recipes) however the method I'm implementing is never executed and was hoping someone could shed some light on my problem.

LoginViewController.h

@protocol GatherDataDelegate;

@interface LoginViewController : UIViewController {
    //lots of ivars
    id <GatherDataDelegate> delegate;

    //more ivars
}
//other properties
@property (nonatomic, assign) id <GatherDataDelegate> delegate;
@end

@protocol GatherDataDelegate <NSObject>
- (void)gatherForUserName:(NSString *)userName gatherForPassword:(NSString *)password;
@end

LoginViewController.m

else if ([dataString isEqualToString:@"Credentials Verified"]){
        [self.delegate gatherForUserName:username gatherForPassword:password]
    }

TableView.h

@interface RootViewController : UITableViewController <GatherDataDelegate>

//ivar and properties

TableView.h

- (void)gatherForUserName:(NSString *)userName gatherForPassword:(NSString *)password;
    NSLog(@"calling gather");
}

It's probably something stupid that I'm missing, like I said, I don't have a lot of experience using delegation, but I see a lot of posts about it. Thanks for any help in advance and taking the time to read this.

+1  A: 

Looks like you did everything right - you created a protocol, implemented it, and sent a message to the delegate... dumb question... are you sure you set the delegate property of the LoginViewController after creating it?

bpapa
Probably another stupid question, but in my Application Delegate I create the LoginViewController and have the Navigation Controller present it in the applicationDidFinishLaunching function. After I created the LoginViewController I set the delegate to self, but it gives me the warning that (myproject)AppDelegate doesn't implement GatherDataDelegate. Is it bad practice to present it in the AppDelegate this way?
Convolution
OK, so that's the problem. You set LoginViewController's delegate to self in your AppDelegate - which means that you're setting the AppDelegate itself as the delegate. But according to the code above, your delegate should actually be RootViewController since it implements the GatherDataDelegate.
bpapa
Thanks for the help Bpapa, this was where I was going wrong, although thanks to TechZen's design critique I'm going to change a thing or two in my app functionality.
Convolution
A: 

Your trying to pass data between two view controller which is bad practice. Instead, you need a data model object that both views communicate with.

First, the login view controller will query the data model for the appropriate login information. If it checks out, the data model will set that user as the current user in the data model such that any future data fetches return data for that user.

Secondly, when the table view controller loads, it simply ask the data model for the information for a user, the data model itself will control which user's data it returns based on the login controller's previous input. the tableview controller only needs to know how to read and display that user info, nothing else.

Such a design is nice and neat and you can add on additional views without having to keep progressively linking all the view controllers together (which will snowball.)

TechZen
Ok, so from a design perspective you think it would just be easier for me to make a CurrentUser class. And have this class be set by the login controller and read by the TableView. Ok that makes more sense. I don't know of any other apps that have an online login system except for facebook. In the future I want the user to be able to save their info so they don't have to login every time. Thanks for the tip.
Convolution
Another kind of stupid question. I'm taking your advice in making a data model object for the current user. If my tableview has all ready been loaded since it's presenting the login view, once the credentials are verified, how does it know to load the users data? Does the login view now send a delegate message saying 'look at the current user object, it's got some data you might find interesting?' or am I going about this wrong. Does it do this by reloading the data in the table?
Convolution
Bpapa's question solved my immediate problem, but thank you TechZen, I'm going to implement a data model in between the two view controllers.
Convolution