iOS開發之登陸與訪客

發現問題與自我革命

在開發中,一直有這樣一種情境:App的未註冊用戶可使用部分功能(訪客視圖),一旦須要使用一些核心功能或者獲取個性化、差別化的服務時,就須要用戶登陸(登陸定製)。通常的狀況是:bash

用戶點擊某個按鈕 ——> 彈出登陸界面 ——> 輸入信息   ——> 登陸驗證  ——> 界面發生變化 
複製代碼

在幾年前作開發時,因爲項目須要快速上線,因此顧不上思考(實際上是本身太菜),直接在須要判斷登陸的界面代碼裏寫上以下代碼:架構

BOOL isLogin;

if(self.isLogin){
    //設置登陸後的界面

}
else{
    //顯示訪客視圖
    //若是用戶點擊登陸則跳轉登陸界面
    //登陸完之後更新當前界面爲登陸後的界面
    
}
複製代碼

時間一長,代碼一多,就會發現不少界面有如上的重複代碼,這很顯然違背了Do not repeat yourself的原則,並且跳轉的邏輯很煩。因而開始改進代碼。ide

最早的一個哥們兒的作法是將登陸字段抽取到一個常量中,須要時判斷該值是否爲真,而後執行相應的邏輯,這樣每一個類中就省去了一個字段。ui

if(CONSTANT.isLogin){
    //設置登陸後的界面

}
else{
    //顯示訪客視圖
    //若是用戶點擊登陸則跳轉登陸界面
    //登陸完之後更新當前界面爲登陸後的界面
    
}
複製代碼

隨着邏輯的增多,發現公用的代碼愈來愈多,因而抽取了父類,這樣邏輯就上移到了父類中,全部子類中不須要有相似isLogin的屬性來判斷用戶是否登陸。atom

if(self.isLogin){
    //設置登陸後的界面

}
else{
    //顯示訪客視圖
    //若是用戶點擊登陸則跳轉登陸界面
    //登陸完之後更新當前界面爲登陸後的界面
    
}
複製代碼

忽然有一天,咱們發現某些App訪客視圖類似度很是大,某些App中的登陸界面也是同樣的,因此發現上面的代碼仍是須要精簡,因而咱們將上面的else部分也上移到父類中,也就是在父類中判斷用戶是否登陸,未登陸顯示訪客視圖,而且將用戶是否登陸的字段isLogin抽離到一個專門的用戶模型中。spa

摸着石頭過河

下面以一個iOS的Demo來說解一下。 主題界面架構是這樣的:code

一開始,進入的時候,都顯示訪客界面,顏色爲 青色,點擊中間的 +彈出登陸界面,點擊登陸界面的 +表示登陸過程,而後主界面顯示登陸後的各個界面,以不一樣顏色代替。

主界面的搭建代碼這裏就不貼了,很簡單,主要講解一下登陸與訪客的邏輯實現。orm

  1. 父類視圖控制器
@interface BaseViewController : UIViewController

@property (nonatomic, assign) BOOL isLogin;

@end


@implementation BaseViewController

-(void)loadView{
    
    //UserModel是一個單例用戶類
    self.isLogin = [UserModel shareInstance].isLogin;
    
    //根據isLogin判斷用戶是否登陸 若是未登陸就顯示訪客視圖 不然就顯示正常界面
    //可是注意 子視圖一樣須要在viewDidLoad中判斷用戶是否登陸
    //在登陸界面 應該從新賦值window的rootViewController 刷新控制器的狀態
    self.isLogin ? [super loadView] : [self setupVisitorView];
    
}

-(void)setupVisitorView{
    
    UIView *view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];
    
    view.backgroundColor = [UIColor cyanColor];
    
    self.view = view;
    
}

@end
複製代碼
  1. 子類視圖控制器(四個子類都差很少,這裏貼一個)
@implementation FourViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    if (self.isLogin) {
        self.view.backgroundColor = [UIColor purpleColor];
    }
}

@end
複製代碼
  1. 中間視圖控制器
@implementation CenterViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    
    [btn setImage:[UIImage imageNamed:@"plusX_Last"] forState:UIControlStateNormal];
    
    btn.bounds = CGRectMake(0, 0, 64, 64);
    
    btn.center = self.view.center;
    
    [self.view addSubview:btn];
    
    if (!self.isLogin) {
        
        self.title = @"未登陸";
        
        [btn addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];
    }
    else{
    
        self.title = @"已登錄";
        
        [btn addTarget:self action:@selector(close) forControlEvents:UIControlEventTouchUpInside];
    
    }
    
    
    
}

-(void)login{


    [UserModel shareInstance].isLogin = YES;
    
    // 必定要從新賦值一次rootViewController
    [self dismissViewControllerAnimated:YES completion:^{
        [UIApplication sharedApplication].keyWindow.rootViewController = [[YFTabbarController alloc]init];
    }];

}

-(void)close{
  
    [self dismissViewControllerAnimated:YES completion:nil];
    
}

@end
複製代碼
相關文章
相關標籤/搜索