How to integrate Login information into MVCS?


#1

Hello,
I really like the pattern for MVCS and I am trying to use it for a small app that is interacting with a web service via JSON data format.
In contrast to the example in chapter 28, the web service I am accessing needs some login information beforehand using a HTTP POST request with login and password information.

Technically, I have no issues with this but regarding the store setup I have some design questions.

  1. I would like to do the login during the init procedure of the Store class. If the login fails for whatever reason, I would like to display an alert view.

  2. the login information (username, password) are entered in a separate controller and then stored via NSDefaults. Is it a good solution to read the login information in the Store via NSDefaults or should this information be passed explicitly to the store?

I would appreciate any comments.

Thanks a lot
Stevie


#2

Give the store a method and a property like:

@property (nonatomic, strong) User *currentUser;

- (void)loginWithUsername:(NSString *)un password:(NSString *)pw completion:(void (^)(User *, NSError *))block;

Inside that method, you’d set up your connection to make the login request. Within the completion block for that connection, you would set the store’s currentUser property to the user object that came back from login and then call the controller block as provided to the store.

Then create a LoginViewController that has the standard two text fields and login button. Give that LoginViewController a property like this:

@property (nonatomic, copy) void (^loginSuccess)(void);

When you want the user to login, the active view controller would do this:

LoginViewController *vc = [[LoginViewController alloc] init];
[vc setLoginSuccess:^{
     // Do stuff here that can only be done once a user has logged in
}];
[self presentViewControllerAnimated:vc completion:nil];

The login button’s action should be:

- (void)login:(id)sender
{
      [[Store store] loginWithUsername:[[self usernameField] text] password:[[self passwordField] text] completion:^(User *u, NSError *err) {
         if(!err) {
              [[self presentingViewController] dismissViewControllerAnimated:YES completion:[self loginSuccess]];
         } else {
             [[self errorLabel] setHidden:NO];
         }
      }];
}

#3

I should also note that, aside from changing the prefix and maybe some tiny look-and-feel details, I use the same LoginViewController for every application I write.