我目前遇到iOS应用程序的问题 我试图采用渐进的登录模式,即:使用可以访问某些应用程序而无需登录。
所需功能如下:
首先,我使用了UIViewController的子类,在指定的初始化程序(initWithCoder)中,它将检查NSUserDefaults以查看用户是否已登录。然后我将其子类化。限制如下:
问题摘要:
我想知道如何有条件地阻止用户访问UIViewController的某些UIView(Controller)和子类,当发生这种情况时会出现UIAlertView。
更新1
类别和/或协议是否可行?
更新2
CodaFi指出单身人士是管理用户状态的绝佳解决方案。
实现后,我现在需要弄清楚如何控制用户的访问权限 当我使用故事板时,我觉得最通用的实现将是子类化UIStoryboardSegue,并且在执行方法检查用户是否正在尝试访问受限制的UIViewController(可能受限制的控制器具有指定所需状态的协议属性:登录/出)。但是,这里的缺陷是您无法在故事板图形编辑器中选择UIStoryboardSegue的类/子类。我知道我可以以编程方式进行,但是这似乎很乏味,因为我必须添加IBActions并将其添加到执行segues的方法中,而且我认为这不会适用于navigationController和tabbarControllers等元素的行为方式。
是否有人有可行的解决方案来限制用户的导航?
更新3
我已经添加了这个问题的答案,但是我仍然认为它没有答案,因为我写的答案没有考虑导航栏控制器之间的段落。但是它可能会帮助一些人。
答案 0 :(得分:2)
所以,我已经使用自定义segues回答了如何做到这一点。
现在我明白我的真正问题是与tabbarcontrollerdelegate协议的精神脱节。
作为防止访问选项卡的解决方案,我已经创建了一个类来处理所述标签栏控制器
#import <Foundation/Foundation.h>
@interface TabBarDelegate : NSObject<UITabBarControllerDelegate,UIAlertViewDelegate>{
UITabBarController *cachedTabBarController;
}
@end
#import "TabBarDelegate.h"
@implementation TabBarDelegate
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
NSLog(@"%s",__FUNCTION__);
NSLog(@"Pretending the user isnt logged in");
if(true){
NSString *message = [NSString stringWithFormat:@"You require an account to access %@",viewController.tabBarItem.title];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Account Required" message:message delegate:self cancelButtonTitle:@"Okay" otherButtonTitles: @"Login",@"Create Account",nil];
[alert show];
//Hold tabbarcontroller property for alert callback
cachedTabBarController = tabBarController;
return false;
}
return true;
}
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
if(cachedTabBarController){
switch (buttonIndex) {
case 1:
//Login
[cachedTabBarController performSegueWithIdentifier:@"tabBarToLogin" sender:cachedTabBarController];
break;
case 2:
//Sign up
[cachedTabBarController performSegueWithIdentifier:@"tabBarToSignup" sender:cachedTabBarController];
break;
default:
break;
}
//Release tab bar controller from memory
cachedTabBarController = nil;
}
}
@end
然后我将它连接到applicationDidFinishLaunching中的appDelegate ......
//Hook up tab bar delegate
mainTabController = (UITabBarController*)self.window.rootViewController;
mainTabBarDelegate = [[TabBarDelegate alloc] init];
mainTabController.delegate = mainTabBarDelegate;
和Voila
答案 1 :(得分:0)
好的,我有一部分解决方案。
它仅适用于您可以选择自定义segue的情况(我只编写推送代码而非模态代码)。
对于需要身份验证的所有控制器的协议“UIViewControllerAuthentication”,此协议包含一种检索所需身份验证状态的方法。
enum authenticationStatus {
notLoggedIn = 0,
noPassword = 1,
loggedIn = 2
};
@protocol UIViewControllerAuthentication <NSObject>
-(enum authenticationStatus)authStatusRequired;
@end
需要身份验证的控制器符合此协议:
-(enum authenticationStatus)authStatusRequired{
return loggedIn;
}
然后将其用于经过身份验证的push segue
@interface SeguePushWithAuth : UIStoryboardSegue
@end
-(void)perform{
NSLog(@"custom segue destination : %@",self.destinationViewController);
NSLog(@"custom segue source : %@",self.sourceViewController);
NSLog(@"custom segue dest conforms to protocol : %i",[self.destinationViewController conformsToProtocol:@protocol(UIViewControllerAuthentication)]);
if([self.destinationViewController conformsToProtocol:@protocol(UIViewControllerAuthentication)]){
UIViewController <UIViewControllerAuthentication> *destination = (UIViewController <UIViewControllerAuthentication> *)self.destinationViewController;
if (!((int)[AccountModel userAuthStatus] >= (int)[destination authStatusRequired])) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Authentication" message:@"You need an account to access this area" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Login",@"Create Account", nil];
//alert
[alert show];
return;
}
}
[[self.sourceViewController navigationController] pushViewController:self.destinationViewController animated:true];
}
@end
然后在uistoryboard中使用自定义segue
这是一个很好的模式,允许目标控制器取消segue 然而,它远非我想要的,因为我希望能够验证将标签栏控制器链接到他们的孩子的segues。