谁应该负责显示带有登录表单的模态对话框?

san*_*mai 6 objective-c storyboard uiviewcontroller ios appdelegate

在我的app委托中,我创建了一个数据模型并将其注入我从故事板获取的根视图控制器,同时从一开始就需要用户的凭据.稍后,在访问某些数据模型方法时,我需要验证用户的密码并重试触发密码重新验证的请求.

最明显的是将此功能构建到可能需要请求此信息的每个视图控制器中,但我想尽可能地避免这种情况,因为它使控制器不那么通用,也使测试更难.在我看来,控制器一定不知道他们给出的模型的内部工作原理.

将此功能添加到模型中对我来说也不合适:管理用户交互完全超出了MVC模型的责任.

谁应该负责显示与相应视图控制器的模态对话框,让用户输入他的凭据?

Ste*_*uda 3

它可以通过回调使用很少的代码行来完成。回调 API 将在模型层定义(因此它是可重用的),但用户交互是在控制器级别实现的(因为这是它所属的位置)。

我不完全确定您的架构到底是什么样子,根据您的描述,我假设应用程序意识到您仅在失败的请求上才经过身份验证(您可能希望存储令牌到期日期并利用它,如果可能的话) 。

基本思想:

在您的模型中,您有一个回调块属性(例如,在客户端类或您使用的任何其他模式上)。

@property (nonatomic, copy) void (^onNonauthenticatedRequest)(NSURLRequest *failedRequest, NSError *error);
Run Code Online (Sandbox Code Playgroud)

当您的请求由于用户未经过身份验证而失败时,您可以在模型层执行此块。

在控制器级别,您有一个控制器提示用户输入凭据(并且具有类似的回调模式)。

client.onNonauthenticatedRequest = ^(NSURLRequest *failedRequest, NSError *error) {

    ABCredentialsViewController *credentialsViewController = [ABCredentialsViewController new];
    credentialsViewController.onAuthenticationSuccess = ^{
        // This gets called after the authentication request succeeded
        // You want to refire failedRequest here
        // Make sure you use a weak reference when using the object that owns onAuthenticationFailure
    };

    credentialsViewController.onAuthenticationFailure = ^(NSError *) {
        // You might want to do something if the user is not authenticated and failed to provide credentials
    }

    [[UIApplication sharedApplication].delegate.window.topViewController presentViewController:credentialsViewController animated:YES];
    // or you could just have a method on UIViewController/your subclass to present the credentials prompt instead
};
Run Code Online (Sandbox Code Playgroud)

逻辑位于正确的位置,如果您想在不同的情况下以不同的方式处理未经身份验证的请求,您可以。