iOS登录流程优化:冷启动时token过期之前自动登录

简介: iOS登录流程优化:冷启动时token过期之前自动登录
  • 1.1 开发步骤
  • 1.2 token信息存储注意事项
  • 3.1 Session 对象的创建
  • 3.2 保存token到UserInfoModel 对象中的时机
  • 3.3 再次打开app的时候获取token
  • 3.4 退出登录或者(token)失效进行信息信息清除
  • 3.5 在登录界面的viewDidLoad 进行判断是否直接进入首页
  • 3.6 token存储区分正式环境和测试环境
  • 3.7 注意事项
  • 单点登录(Single Sign On)

前言

需求:

1、冷启动app时,若token不过期,就使用最近一次登录的token进行数据请求

2、优化token的存储方式:之前只是存储在内存,只要杀死app,重新打开就要求重新登录。现在改为将token信息存储到本地数据库,每次打开app使用最近一次登录获得的token。

3、 调试技巧 如果BGFMDB的表新增字段,可更换一下表名,避免找不到字段,数据更新失败

4、原文 https://kunnan.blog.csdn.net/article/details/105202605

5、付费文章:iOS App登录流程优化:如果 token不过期,就使用最近一次登录的token【修订版】

本文限时免费

I 、 步骤

1.1 开发步骤

  • I、保存token到UserInfoModel 对象中
  • II、再次打开app的时候获取token
  • III、退出登录或者(token)失效进行信息信息清除
  • IV、在登录界面的viewDidLoad 进行判断是否直接进入首页
  • V :token存储区分正式环境和测试环境(UserInfoModel 对象新增一个当前token的域名属性currentHost,用于查询判断)

5.1) 更换表名

5.2)UserInfoModel新增字段currentHost,

5.3)查询token新增条件currentHost

5.4) 存储token新增字段currentHost



1.2 token信息存储注意事项

登录账号得到的token信息。最好不要作为一个独立的单利对象存储;而是将它作为单例对象的属性userInfo,这样便于切换账号存储token和其他账号信息

  • 如果之前是使用独立的单利对象UserInfoModel ,为了兼容代码可以这么做
/**
 登录账号得到的token信息。最好不要作为一个独立的单利对象存储;而是将它作为单例对象的属性userInfo,便于切换账号存储token和其他账号信息。
 */
+ (instancetype)shareUserInfoModel{
    return [QCTSession.shareQCTSession userInfo];
}

使用线程安全模式来创建共享实例,并使用条件编译#if进行ARC、MRC的适配

https://kunnan.blog.csdn.net/article/details/74295191

II、 整体思路

保存和清除token

  • 使用BGFMDB 进保存最近一次登录的token
pod 'BGFMDB', '~> 2.0.13'  #2.0.9
  • 切换账号的时候更换token
  • 请求接口发现token 失效的时候,回到登录界面

III、核心代码

3.1 Session 对象的创建

使用HSSingleton工具类实现单例,并将包含登陆token及其他有状态相关字段的userInfo对象作为单例对象的属性

HSSingletonH(Session);
HSSingletonM(Session);
+ (void)SaveUserInfo:(UserInfoModel *)userInfo{
    QCTSession.shareQCTSession.userInfo = userInfo;
}

存储token信息

#pragma mark - ******** iOS 优化登录流程:【打开app,如果 token不过期,就使用最近一次登录的tokenn进行接口请求。】(现状是每次打开app都会重新登录)
+ (void)saveModelWithModel:(UserInfoModel*)userModel{
    [self emptySeeionLocal];
    userModel.bg_tableName = QCTUserInfoModelTableName;
    BOOL isSave = [userModel bg_save];// 保存方法
    if (isSave) {
        NSLog(@"token保存成功:%@",userModel.mj_keyValues);
    }else{
        NSLog(@"token保存失败:%@",userModel.mj_keyValues);
    }
}
+(void)emptySeeionLocal{
    NSMutableArray *tmparr = [NSMutableArray arrayWithArray:[[self class] bg_find:QCTUserInfoModelTableName where:nil] ];
    // 先删除
    for (UserInfoModel *loginModel in tmparr) {
        NSString *where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"bg_id"),bg_sqlValue(loginModel.bg_id)];
        BOOL isDelete = [UserInfoModel bg_delete:[NSString stringWithFormat:@"%@",QCTUserInfoModelTableName] where:where];
        NSLog(@"删除重复数据%@:%@",isDelete?@"成功":@"失败",loginModel.mj_keyValues);
        //            break;
        //
    }
}

获取token信息

+ (instancetype)getmodel4LoginSeesion{
    NSMutableArray *tmparr = [NSMutableArray arrayWithArray:[[self class] bg_find:QCTUserInfoModelTableName where:nil] ];
    if(tmparr.count>0   ){
        UserInfoModel *userModel = tmparr.firstObject;
//        QCTSession.shareQCTSession.userInfo = userModel;
        [ QCTSession SaveUserInfo:userModel];
        NSLog(@"获取的token 信息%@",userModel);
        return tmparr.firstObject;
    }
    NSLog(@"获取的token userModel.shareUserInfoModel %@",UserInfoModel.shareUserInfoModel);
    //
    return UserInfoModel.shareUserInfoModel;
}

3.2 保存token到UserInfoModel 对象中的时机

  • 登录的时候
[ Session SaveUserInfo:userModel];
 [UserInfoModel saveModelWithModel:userModel];
  • app 退出的时候:applicationWillTerminate 、applicationWillResignActive
- (void)applicationWillTerminate:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    [UserInfoModel saveModelWithModel:UserInfoModel.shareUserInfoModel];
}

3.3 再次打开app的时候获取token

#pragma mark - ******** 获取token信息
- (void)initInfo{
    QCTSession.shareQCTSession.tmpUserInfoModel = nil;
    [UserInfoModel getmodel4LoginSeesion];// 获取会话
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self initInfo];
}

3.4 退出登录或者(token)失效进行信息信息清除

  • 在 application :didFinishLaunchingWithOptions: 方法进行监听
__weak __typeof__(self) weakSelf = self;
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:kExitlogshowLoginViewNotification object:nil] subscribeNext:^(NSNotification *notification) {
        NSString *tmp = @"";
        if(notification.object){
            tmp = notification.object;
            [weakSelf.window showHUDMessage:tmp afterBlock:^(id  _Nonnull sender) {
                [weakSelf setupExitlogout];
            }];
        }else{
//            tmp = @"";
            [weakSelf setupExitlogout];
        }
    }];
  • 退出登录(token过期)的处理
/**
 1、移除极光的别名
 2、初始化一些信息
 3、清除账户信息缓存(本地数据库和内存中的token信息)
 */
- (void)setupExitlogout
{
    [JPUSHService setTags:nil alias:@"" callbackSelector:@selector(tagsAliasCallback:tags:alias:) object:self];
    [UserInfoModel cleanInfoWithblock:^(id sender) {
        //3、登录
            UserInfoModel.shareUserInfoModel.token = nil;
        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        [appDelegate setupLoginV];
    }];
}
  • 清除本地数据库的token
+ (void)cleanInfoWithblock:(void (^)(id sender))block{
    [[UserInfoModel shareUserInfoModel] cleanInfo];
    if(block){
        block(nil);
    }
}
- (void)cleanInfo{
#pragma mark - ******** 包括清除本地数据库的token
    [[self class] emptySeeionLocal];//
        [self  setToken:nil];
        _CurrentSysUser = nil;
    //    _
    [QCTSession shareQCTSession].tmpUserInfoModel = nil;
}

3.5 在登录界面的viewDidLoad 进行判断是否直接进入首页

  • viewDidLoad 早createSubView的时候进行判断,是否直接进入首页
if(UserInfoModel.shareUserInfoModel.isLoginByToken){
            [[self class] jumpHome];
            return;
        }
  • 判断是否有token
/**
 判断是否有token
 */
- (BOOL)isLoginByToken{
    if(![NSStringQCTtoll isBlankString:UserInfoModel.shareUserInfoModel.token]){
        return YES;
    }
    return NO;
}

3.6 token存储区分正式环境和测试环境

  • UserInfoModel 对象新增一个当前token的域名属性currentHost,用于查询判断环境
  • BGFMDB如果新增字段,就需要更换一下表名
#warning  BGFMDB如果新增字段,就需要更换一下表名,否则在旧表会找不到字段,无法更新数据
 2021-01-29 17:16:10.418453+0800 Housekeeper[15013:1071895] [logging] table QCTUserInfoModelTableName0401 has no column named BG_IsreqGetCurrentSysUsering in "insert into QCTUserInfoModelTableName0401(BG_currentHost,BG_BearerToken,BG_token,BG_DictionariesEnum,BG_DictionariesEnumDictionary,BG_loginCode,BG_isGotoChangePassword,BG_HaveDefaultLevel,BG_bg_updateTime,BG_loginMessage,BG_IsreqGetCurrentSysUsering,BG_IsTobacco,BG_bg_createTime,BG_MsgsourceStr,BG_isShowBindingMobileNote) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"
  • 根据域名进行存取token的

image.png

NSString*  where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"currentHost"),bg_sqlValue(currentHost)];
   NSMutableArray *tmparr = [NSMutableArray arrayWithArray:[[self class] bg_find:QCTUserInfoModelTableName where:where] ];

存储token信息

+ (void)saveModelWithModel:(UserInfoModel*)userModel{
    [self emptySeeionLocal];
    userModel.bg_tableName = QCTUserInfoModelTableName;
    userModel.currentHost = currentHost;
    BOOL isSave = [userModel bg_save];// 保存方法
    if (isSave) {
        NSLog(@"token保存成功:%@",userModel.mj_keyValues);
    }else{
        NSLog(@"token保存失败:%@",userModel.mj_keyValues);
    }
}

3.7 注意事项

  • 2020-03-30 19:23:12.877204+0800 Housekeeper[5577:1118700] DB Error: 1 "duplicate column name: BG_CompanyId"BGFMDB 不支持大小写,因此保存的对象不能有大小写的两个字段
@property (copy, nonatomic) NSString *companyId;
//@property (strong, nonatomic) NSString *CompanyId;
  • 2020-04-01 16:18:32.127564+0800 retail[8875:1402725] [logging] table QCTUserInfoModelTableName has no column named BG_currentHost

如果新增字段,就需要更换一下表名

IV、see also


目录
相关文章
|
6月前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
227 3
|
6月前
|
iOS开发 开发者
苹果iOS App Store上架操作流程详解:从开发者账号到应用发布
很多开发者在开发完iOS APP、进行内测后,下一步就面临上架App Store,不过也有很多同学对APP上架App Store的流程不太了解,下面我们来说一下iOS APP上架App Store的具体流程,如有未涉及到的部分,大家可以及时咨询,共同探讨。
|
6月前
|
安全 数据安全/隐私保护 iOS开发
iOS App 上架流程图文教学
在上架App 之前必须先准备好开发者帐号,但申请开发者帐号因法兰克早在之前已经申请好了,故就跳过此步骤,直接从产生凭证到上传App开始讲起。首先,要将自己辛苦写好的App 送审的话,则要依序做完下列几件事情即可。
|
14天前
|
安全 Android开发 iOS开发
深入探索iOS与Android系统的差异性及优化策略
在当今数字化时代,移动操作系统的竞争尤为激烈,其中iOS和Android作为市场上的两大巨头,各自拥有庞大的用户基础和独特的技术特点。本文旨在通过对比分析iOS与Android的核心差异,探讨各自的优势与局限,并提出针对性的优化策略,以期为用户提供更优质的使用体验和为开发者提供有价值的参考。
|
4月前
|
开发工具 iOS开发 计算机视觉
|
2月前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
150 0
|
6月前
|
缓存 开发工具 iOS开发
优化iOS中Objective-C代码调起支付流程的速度
优化iOS中Objective-C代码调起支付流程的速度
104 2
|
6月前
|
数据安全/隐私保护 iOS开发 开发者
uniapp IOS从打包到上架流程(详细简单) 原创
uniapp IOS从打包到上架流程(详细简单) 原创
240 1
|
6月前
|
机器学习/深度学习 测试技术 API
iOS系统下轻松构建自动化数据收集流程
iOS系统下轻松构建自动化数据收集流程
80 0
|
6月前
|
iOS开发 开发者 UED
2023年iOS App Store上架流程详解(上)
在2023年,随着苹果发布机制的微调,有些关于iOS App上架流程的资料已经过时。本文将根据最新的要求和经验,详细介绍iOS App上架的流程。