用于身份验证的Cocoa设计模式

时间:2011-09-24 21:47:23

标签: iphone objective-c ios design-patterns authentication

在为iOS开发一段时间之后,我已经对这种语言感到满意,并且正在努力改进设计结构良好的应用程序。最初我的重点是看到功能上的东西,所以我最终得到了巨大的视图控制器,这些控制器是可怕的架构。现在,我正在学习分离我的模型类,并试图使我的架构更加模块化。我非常感谢有关以下示例情况的任何建议:

我正在开发一个应用程序,其中(除其他外)从服务器中提取文章列表并显示它们。但是,必须对用户进行身份验证才能检索此列表。由于应用程序的其他方面使用相同的身份验证,我希望单个类来管理身份验证。目标是当任何控制器从模型请求需要身份验证的数据时,如果用户未经过身份验证,将自动显示身份验证提示。

我希望创建以下内容:

查看
- ArticlesView
- AuthenticationView

CONTROLLER
- ArticlesViewController
- AuthenticationViewController
- ArticleManager(单身人士)
- AuthenticationProvider(singleton)

MODEL
- 文章

当应用程序首次加载时,执行将到达ArticlesViewController的viewDidLoad方法。在这个方法中,我获得了ArticleManager的共享实例,将身份验证类指定为身份验证提供程序,并要求它提供最近文章的列表。

// ArticlesViewController.m
-(void) viewDidLoad {
    ...
    AuthenticationProvider *authProvider = [AuthenticationProvider sharedInstance];
    [[ArticleManager sharedInstance] setAuthenticationProvider:authProvider];
    [[ArticleManager sharedInstance] fetchNewArticles];
}

如果不需要身份验证,ArticleManager将成功从服务器检索列表并发布通知,让任何感兴趣的人知道文章已被检索。 ArticlesViewController将处理此通知:

// ArticlesViewController.m
- (void) handleNewArticlesNotification:(NSNotification *)note {
    [self updateUI];
}

但是,如果需要身份验证,则需要在获取和显示文章之前向用户显示登录屏幕。所以我想象ArticleManager做了这样的事情:

// ArticleManager.m
- (void) fetchNewArticles {
    if( [self.authenticationProvider isAuthenticated] ){
        // go fetch list from the web
    }
    else {
        [self.authenticationProvider presentAuthenticationRequest];
    }
}

现在,在这一点上,我遇到了一些困难,充实了其余的细节。 AuthenticationProvider可以从AppDelegate的窗口的rootViewController将AuthenticationViewController呈现为模态视图控制器,AuthenticationProvider将是AuthenticationViewController的委托。 AuthenticationViewController可能对它正在采取的实际操作感到愚蠢,并且会让它的委托(AuthenticationProvider)完成对用户进行身份验证的工作。一旦用户通过身份验证,AuthenticationProvider将关闭模态视图控制器(AuthenticationViewController)。

但是如何通知ArticleManager其请求的身份验证已完成?它需要能够分别处理成功和失败的身份验证尝试。成功的身份验证最终会导致再次调用fetchNewArticle。

一种想法是将ArticleManager作为AuthenticationProvider的委托。这似乎适用于这种情况,但还有其他模型管理器也可以依赖AuthenticationProvider。据推测,如果AuthenticationProvider不是单例,这将得到解决。这会是一个体面的设计方法吗?

感谢您抽出宝贵时间帮助我了解良好的设计方法。我已经编码了几次,但总是陷入困境/困惑。此外,如果整个方法需要重新设计,请随时指向另一个方向。

非常感谢!

2 个答案:

答案 0 :(得分:1)

我一直使用Global NSNotifications在用户登录或注销时发布。每个以不同方式呈现数据的视图控制器都可以订阅这些通知,并在事件发生时相应地更新自己。

这很好,因为您可能已经有其他视图(可能在其他标签中)已经加载,并且需要在用户登录或注销时刷新。

答案 1 :(得分:0)

  

一想法是将ArticleManager作为委托   的AuthenticationProvider。这似乎适用于这种情况,但有   其他模型管理器也可以依赖AuthenticationProvider。   如果AuthenticationProvider不是,那么可能会解决这个问题   单身。这会是一个体面的设计方法吗?

也许您可以让AuthenticationProvider单例提供AuthenticationSession对象,将调用者设置为AuthenticationSession的委托,并要求AuthenticationSession执行身份验证。