36

iOS 登录、退出流程整理

 5 years ago
source link: http://www.cocoachina.com/ios/20181122/25561.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

写在前面

仅以此文记录APP登录、退出登录比较简单核心的流程。

流程梳理

登录流程有两种情况,1、未登录时,打开APP先进入登录页面,点击登录后进入首页。2、已登录时,打开APP直接进入首页。

这里我们已最精简的流程图表示这两种登录情况。

1:未登录情况

fIzUZrf.png!web

2:已登录情况

ZBzEBzj.png!web

代码编程

我项目是用的RAC+MVVM开发的,可能有些地方架构不同,但是道理都是相通的。

一、LoginService

首先继承NSObject创建LoginService用来做“登录”功能的数据处理。还有在登录成功后需要存储用户的一些信息,这些信息往往我们将其以model的形式存储。

在LoginService.h中最主要的两个方法。

@property (nonatomic, strong) UserInfoModel *signUser;

+ (instancetype)shareInstance;

- (RACSignal *)loginWithLoginName:(NSString *)loginName
                         loginPwd:(NSString *)loginPwd;
                         
- (void)logOut;

在.m中:

1、先说- (RACSignal *)loginWithLoginName:(NSString *)loginNameloginPwd:(NSString *)loginPwd方法。请求服务器登录成功后接受返回的参数,返回的用户信息我们用signUser接收。

if ([responseObject isKindOfClass:[NSString class]]) {
            //
            return @(NO);
        } else {
            NSDictionary *resultDic = responseObject[@"result"];
            UserInfoModel *userInfo = [UserInfoModel yy_modelWithDictionary:resultDic];
            self.signUser = userInfo;
            
            NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
            [userDefault setObject:loginName forKey:USERNAME];
            [userDefault setObject:[CryptoHelper Encrypt:loginPwd] forKey:PASSWORD];
            [userDefault setObject:@"ISLOGIN" forKey:ISLOGIN];
            NSData *signUserData = [NSKeyedArchiver archivedDataWithRootObject:userInfo];
            [userDefault setObject:signUserData forKey:SIGNUSERINFO];
            [userDefault synchronize];
            
            self.isLogin = YES;
            
            return @(YES);
        }

在这个方法中,使用NSUserDefaults将用户名和密码进行本地化存储,(注意:密码不要以明文方式存储,需要加密)。另:将登录状态也存储在NSUserDefaults本地中,以便在AppDelegate中使用。

这里有一个点,我们都知道NSUserDefaults是不可以直接存储对象的。但是我们又想存signUser这个UserInfoModel。这里需要对UserInfoModel进行处理。UserInfoModel继承自NSObjec,并遵循NSCoding协议。并实现两个NSCoding代理方法:

//1:
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super init]) {
        self.adminID = [aDecoder decodeObjectForKey:@"adminID"];
        self.adminName = [aDecoder decodeObjectForKey:@"adminName"];
    }
    return self;
}
//2:
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.adminID forKey:@"adminID"];
    [aCoder encodeObject:self.adminName forKey:@"adminName"];
}

这样我们在存储model对象的时候,先将model转成NSData类型,然后将data存储即可。

NSData *signUserData = [NSKeyedArchiver archivedDataWithRootObject:userInfo]; [userDefault setObject:signUserData forKey:SIGNUSERINFO];

2、实现logOut方法

在注销登录的方法中,将本地存储的密码、登录状态标识、用户信息清除,这里我们保留了“账号”,后面将会提到这个用处。

- (void)logOut {
    self.isLogin = NO;
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
//    [userDefault removeObjectForKey:USERNAME];
    [userDefault removeObjectForKey:PASSWORD];
    [userDefault removeObjectForKey:ISLOGIN];
    [userDefault removeObjectForKey:SIGNUSERINFO];
    [userDefault synchronize];
}

3、这里说一下signUser属性变量

在这里我将LoginService做了一个单例,因为这里面的signUser会在项目中其他地方用到,所以这里我使用了懒加载。在懒加载中先判断有没有登录状态的记录,如果有的话直接从本地里面取出signUser。没有的话给signUser进行初始化,具体见下面代码:

这里也有一个点:从本地取出之前存储的model对象。在这里操作的时候先将[userDefault objectForKey:SIGNUSERINFO]转换为NSData,然后使用NSKeyedUnarchiver解档成 UserInfoModel。如下代码:

- (UserInfoModel *)signUser {
    if (!_signUser) {
        NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
        if ([[userDefault objectForKey:ISLOGIN] isEqualToString:@"ISLOGIN"]) {
            NSData *signUserData = [userDefault objectForKey:SIGNUSERINFO];
            _signUser = (UserInfoModel *)[NSKeyedUnarchiver unarchiveObjectWithData:signUserData];
        } else {
            _signUser = [[UserInfoModel alloc] init];
        }
    }
    return _signUser;
}

二、AppDelegate

在APPDelegate中,判断本地是否有存储的ISLOGIN标识,进行不同逻辑的跳转。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    BOOL isLogin = [[userDefault objectForKey:@"ISLOGIN"] isEqualToString:@"ISLOGIN"];
    
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[UIViewController new]];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
    
    if (isLogin) {
        HomePageVC *vc = [[HomePageVC alloc] init];
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
        self.window.rootViewController = nav;
    } else {
        LoginVC *vc = [[LoginVC alloc] init];
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
        nav.navigationBarHidden = YES;
        self.window.rootViewController = nav;
    }
    return YES;
}

三、SettingVC

在这个界面点击退出登录按钮执行如下方法:

在这里最后不要用push或pop来切换界面。采用直接改变[UIApplication sharedApplication].keyWindow.rootViewController的方法。

        [self.viewModel logout];
        LoginVC *vc = [[LoginVC alloc] init];
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
        [UIApplication sharedApplication].keyWindow.rootViewController = nav;

总结

以上就是登录->退出登录的核心逻辑,在此基础上再添加别的业务逻辑。比如启动页,引导页之类的。

作者:劉光軍_Shine

链接:https://www.jianshu.com/p/0442024c8045


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK