1

我正在尝试创建一个在首次加载时需要登录的应用程序。用户成功登录后,凭据将存储在钥匙串中,因此用户不必继续登录。

这是我编写的以下代码的快速模型;是否使用AppDelegate正确的方法来处理首先显示哪个视图?

AppDelegate.h

#import <UIKit/UIKit.h>
#import "KeychainItemWrapper.h"
#import "ViewController.h"
#import "TestBViewController.h"
#import "User.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) TestBViewController *mainVC;  //  User see's after loggin in
@property (strong, nonatomic) User *user;
@property (strong, nonatomic) KeychainItemWrapper *keychainItem;

- (void)saveKeychainUsername:(NSString *)username andPassword:(NSString *)password;
- (void)loadLoggedInViewControllers;

@end

AppDelegate.m

#import "AppDelegate.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"AppUniqueID" accessGroup:nil];

//    [self.keychainItem resetKeychainItem];

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

// Override point for customization after application launch.

NSString *password = [self.keychainItem objectForKey:(__bridge id)(kSecValueData)];
NSString *username = [self.keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];

NSLog(@"username: %@, password: %@", username, password);

if ([username length] <= 0 || [password length] <= 0) {
    // Login VC
    ViewController *loginVC = (ViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:@"Login"];
    self.window.rootViewController = loginVC;
} else {
    [self loadLoggedInViewControllers];
}

return YES;
}

- (void)loadLoggedInViewControllers {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

//  Attempt to login user
self.user = [[User alloc] init];

self.user.name = @"Bob";
self.user.hasAccess = YES;
//  If user is no longer valid (for whatever reason) remove his keychain information so we can save the new ones.

//  Valid user! Skip Login VC
self.mainVC = (TestBViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:@"Main"];
self.mainVC.user = self.user;

self.window.rootViewController = self.mainVC;
}

ViewController.m - 把它想象成我的 LoginViewController

- (IBAction)storePassButtonTap:(id)sender {

if ([[username text] length] > 0 && [[password text] length] > 0) {
     AppDelegate *shareDelegate = [[UIApplication sharedApplication] delegate];

    [shareDelegate saveKeychainUsername:[username text] andPassword:[password text]];

    [shareDelegate loadLoggedInViewControllers];
} else {
    if ([[username text] length] <= 0) {
        //  Error message
    }

    if ([[password text] length] <= 0) {
        //  Error message
    }
}
}
4

2 回答 2

2

我不建议这样做。我过去曾这样做过,并且我遇到过这样的问题,例如,一旦我像这样更改 appdelegate 的 rootviewcontroller 属性,方向代表就无法正常工作。看起来它在 iOS 6 中已修复,但我的理解是这是不寻常的事情,不应该这样做。

取而代之的是有一个虚拟的视图控制器作为根视图控制器,并添加其他视图控制器作为它的子视图控制器。您可以通过这种方式删除和添加任何视图控制器。

于 2013-05-24T21:21:40.207 回答
1

我个人不会。我使用故事板并将视图控制器设置为根。如果我需要这样做,我会将视图控制器留空(如果登录需要一分钟,可能会有一个活动指示器),在此处运行登录代码,然后移动到登录 segue 或主应用程序 segue。

确保接下来的两个屏幕都隐藏了后退按钮,这样用户就无法返回此屏幕。

我喜欢离开 appDeleage 来重新建立 tcp 连接并在进入后台时关闭它们。

于 2013-05-24T16:28:06.130 回答