用户进行身份验证后如何切换视图

时间:2011-10-17 23:28:07

标签: objective-c cocoa

我正在学习并努力掌握正确实施声音MVC设计的方法。

我有一个由NSWindowController管理的单一窗口应用程序,有两个用于登录的视图控制器(LoginViewController)和一个用户登录后的另一个视图(MainViewController)。

// MyWindowController.h
@interface MyWindowController : NSWindowController {
    IBOutlet NSView* myTargetView;

    LoginViewController *loginViewController;
    MainViewController *mainViewController;
}

- (void)changeViewController:(NSInterger)view;

@property (nonatomic, retain) LoginViewController *loginViewController;

在MyWindowController的awakeFromNib方法中,我正在检测用户是否通过NSUserDefaults登录:

// MyWindowController.m
// pseudocode below
- (void)awakeFromNib
    IF the user is logged in
        set myTargetView to the view of MainViewController
    ELSE the user is not logged in
        set myTargetView to the view of LoginViewController

这很好用,然后在我的LoginViewController视图中,我有以下插座和操作:

// LoginViewController.h
@interface LoginViewController : NSViewController {
    IBOutlet NSTextField *username;
    IBOutlet NSSecureTextField *password;
}


- (IBAction)authenticate:(id)sender;

我的验证方法:

// LoginViewController.m
- (IBAction)authenticate:(id)sender

    ...

    IF (authenticated) {
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        [defaults setInteger:1 forKey:@"UserAuthenticated"];
    } ELSE {
        // Update loginView to display "Wrong username/password"
    }

我的问题是,一旦用户通过身份验证并更新了用户的默认值以反映这种情况。如何正确命令MyWindowController交换到MainViewController?

我正在学习MyWindowController中的KVO以检测密钥:UserAuthenticated是否为true,如果是,则在主视图中交换。但是我不确定这是否是正确的方法。

如果我的应用程序设计存在致命错误,请更正并向我解释原因。

2 个答案:

答案 0 :(得分:1)

你可以做一个委托,但这是不灵活的,不是最佳设计。通知可以,但是随着项目的增长,它们很难跟踪正在发生的事情。 我建议使用KVO方法,因为如果您稍后更改设计,它会更灵活。有点像:

void *kAuthChangedContext = &kAuthChangedContext;

@implementation MyWindowController

- (void) awakeFromNib {
    [[NSUserDefaults standardUserDefaults] addObserver:self 
        forKeyPath:@"UserAuthenticated" options:0 context:kAuthChangedContext];
}

- (void) updateViews {
    // Update your view state here
}

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
    change:(NSDictionary *)change context:(void *)context {

    if (kAuthChangedContext == context) {
        [self updateViews];
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object
            change:change context:context];
    }
}

@end

不要忘记在dealloc方法中删除自己作为观察者。干杯!

答案 1 :(得分:0)

您可以为此实现委托或使用NSNotificationCenter发布通知。