iOS小技能: app侧退出登录处理流程

2,209 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情

引言

登录处理流程: 上篇:前置知识blog.csdn.net/u011018979/… 下篇:核心实现(打开app,如果 token不过期,就使用最近一次登录的token进行接口请求)blog.csdn.net/u011018979/…

本文讲解退出登录处理流程:

  1. 退出登录时清理相关的数据:token、消息推送别名

  2. 移除相关通知:退出登录,切换UIWindow的主控制器之前,最好移除相关控制器监听的通知。

在 ARC 环境下,viewController 可能被放在 autorelease 池中,因此 viewController 被pop后不一定立即被销毁,所以一些对实时性要求很高的内存管理逻辑可以写在退出登录逻辑这里(而不是写在dealloc内)

I 清理当前账户相关信息(token、消息推送别名)

1.1 退出登录(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;
    

}


退出登录时清理消息推送的订单相关的打印数据

    
//     退出登录时清理消息推送的订单相关的打印数据
    [ERPPrintInfo bg_clearAsync:QCTSNPrinterInfoTableName4push complete:^(BOOL isSuccess) {
        
    }];
    

1.2 移除消息推送别名

blog.csdn.net/z929118967/… 需求:账号退出登陆后无法收到推送功能

- (void)deleteAliaWithblock:(void (^)(id sender))block
{
    WEAKSELF
    //Method - deleteAlias:completion:seq:


    [JPUSHService deleteAlias:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
        if (iResCode == 6002 || iResCode == 6014 || iResCode == 6020 || iResCode == 6021 || iResCode == 6022) {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [weakSelf deleteAliaWithblock:block];
            });
            
        } else if(iResCode == 0){
//            NSLog(@"清除别名成功");

            if (block) {
                block(nil);
            }
            return ;
        }else{
            NSLog(@"清除别名 失败code:%ld",(long)iResCode);

            
        }
        
    } seq:[_store.id integerValue]];

}


II 移除相关通知

2.1 背景

在 ARC 环境下,viewController 可能被放在 autorelease 池中,因此 viewController 被pop后不一定立即被销毁,所以一些对实时性要求很高的内存管理逻辑可以写在退出登录逻辑这里(而不是写在dealloc内)

2.2 问题

没有移除首页等控制器的相关通知,有可能引起发起多次的接口请求,尤其是登录之后请求的第一个接口。

解决方式:退出登录时,遍历TabBarController的子控制器移除相关通知。

+ (void)removeNoti{
    
    UIViewController *rootViewController =UIApplication.sharedApplication.delegate.window.rootViewController;
    
    
    if(![NSStringFromClass(rootViewController.class) isEqualToString:@"HWTabBarController"] ){
        

        return ;
        
        
    }
    
    for (HWNavigationController* nav in rootViewController.childViewControllers) {
        
        NSLog(@"removeObserver:%@",nav);
        if(![NSStringFromClass(nav.class) isEqualToString:@"HWNavigationController"] ){
            
            [[NSNotificationCenter defaultCenter]removeObserver:nav];

            break ;
            
            
        }

        for (UIViewController* vc in nav.childViewControllers) {
            NSLog(@"removeObservervc:%@",vc);

            [[NSNotificationCenter defaultCenter]removeObserver:vc];
            

        }
        
        
        

        
    }

    
}

[[NSNotificationCenter defaultCenter]removeObserver:vc]; 方法只能移除- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject; 方法添加的通知,无法移除rac_addObserverForName添加的通知。