2013-07-19 181 views
0

所以,我有我的應用程序中是否沒有邏輯,基於用戶的憑據的問題,我的應用程序的主視圖應顯示在主視圖中的tableview登錄視圖已被駁回或只顯示後登錄視圖後的主視圖已被解除。視圖控制器堆棧

所以現在,我發送一個HTTP POST請求從哪裏獲得令牌回來,然後讓之後的另一個調用來獲取用戶擁有的列表項數量的服務器,可以說遊戲。

如果用戶只有一個遊戲,我想要顯示主視圖,但是如果用戶有多個遊戲,那麼用戶應該看到一個tableview,按下其中一個單元然後以模式方式解除tableview顯示主視圖。

通常我有這3個控制器,至少這是我正在考慮實施應該怎樣,不知道它的正確的方式的方式。

所以假定控制器A是登錄,控制器B是的tableview,和控制器C是MAINVIEW。

控制器C位於堆棧的底部,而控制器A位於頂部。但是,潛在地,控制器B可能會或可能不會基於來自控制器A的信息顯示。當我說棧底時,我的意思是如果用戶還沒有登錄,那麼登錄視圖(控制器A)將被呈現在主視圖(控制器C)上沒有動畫。所以在技術上,主視圖(控制器C)總是被加載,但數據沒有被提供給它,只有在登錄視圖被正確提交的憑證解除之後。

以下是在mainviewcontroller(控制器C)中實施的一些方法,用於檢查用戶是否已登錄,如果沒有,則應用程序技術上會首先通過mainviewcontroller並呈現登錄視圖。我明白,這是去與應用開發的登錄模式的方法,但我不是100%:

- (void)showLoginViewAnimated:(BOOL)animated { 
    NSLog(@"[MainViewController] Show login view controller"); 
    PowerOneLoginTabBar *loginVC = [[PowerOneLoginTabBar alloc] init]; 
    [self presentViewController:loginVC animated:NO completion:nil]; 
} 

- (void)logoutHandler:(NSNotification *)notification { 
    NSLog(@"[MainViewController] Logout handler"); 
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"userLoggedIn"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 

    [self showLoginViewAnimated:YES]; 
} 

在MAINVIEW的viewDidLoad中(視圖 - 控制C):

BOOL isUserLoggedIn = [[NSUserDefaults standardUserDefaults] boolForKey:@"userLoggedIn"]; 
    if(!isUserLoggedIn || (!setAuthenticationKey || [setAuthenticationKey isKindOfClass:[NSNull class]])) 
     [self showLoginViewAnimated:NO]; 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(logoutHandler:) name:LOGOUT_NOTIFICATION object:self.view]; 

這裏是我的登錄處理在登錄的ViewController實現(控制器A):

- (void)authenticateHandler:(NSNotification *)notification { 
    NSLog(@"[LoginViewController] Authenticate handler"); 

    NSDictionary *userDict = [notification userInfo]; 



    BOOL isUserAuthenticated = 
    //[username isEqualToString:[userDict objectForKey:@"username"]] && 
    //[password isEqualToString:[userDict objectForKey:@"password"]] && 
    [api_Key isEqualToString:[userDict objectForKey:@"apiKey"]] && 
    ([_auth isEqualToString:[userDict objectForKey:@"authKey"]]); 

    [[NSUserDefaults standardUserDefaults] setBool:isUserAuthenticated forKey:@"userLoggedIn"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 

    if(isUserAuthenticated){ 

     NSLog(@"Authentificated"); 
     [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 

    } else { 
     NSLog(@"Not Authentificated"); 
     [self showAlert]; 
    } 
} 

而在一個loginView(視圖控制器A)的viewDidLoad方法:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(authenticateHandler:) name:AUTHENTICATE_NOTIFICATION object:self]; 

如果你們能夠給我一種模式或防呆在這怎麼可能做到這將是巨大的理論。

因爲此刻,我目前解僱與所示的MAINVIEW登錄視圖,但然後我呈現的tableview模態(動畫),這是不desireable。所以你可以想象一個視圖被動畫解散,然後你看到主視圖,然後通過動畫在主視圖上顯示tableview。我不希望用戶直到他們登錄後才能看到主視圖,並且他在選擇遊戲後查看詳情,除非用戶只有一個遊戲!

還記得在視圖A和C之間顯示tableview的唯一原因是因爲用戶可能有超過1個遊戲,但是如果他們只有1個遊戲,則從控制器A到控制器C而不是控制器A到控制器B到控制器C.

回答

1

我不知道我完全理解這個問題,但這裏的一些建議,我希望是有用的:

一個UINavigationController是特別適用於VCS的堆棧,尤其是,在我看來,在你出席的情況。

主要vc可以檢查用戶的登錄狀態,並提供登錄vc或不。它可以通過假設用戶有一個以上的遊戲可供選擇,打造VC堆棧如下開始:

- (void)viewDidAppear:(BOOL)animated { 

    // notice I moved the logical or to make the BOOL more meaningful 
    BOOL isUserLoggedIn = [[NSUserDefaults standardUserDefaults] boolForKey:@"userLoggedIn"] || (!setAuthenticationKey || [setAuthenticationKey isKindOfClass:[NSNull class]]); 

    if (!isUserLoggedIn) { 
     SelectGameVC *selectGameVC = // not sure how you build this, either alloc-init or get from storyboard 
     // notice animation==NO, we're putting this on the stack but not presenting it 
     [self.navigationController pushViewController:selectGameVC animated:NO]; 
     LoginVC *loginVC = // alloc or use UIStoryboard instantiateViewControllerWithIdentifier 
     // we push this one with animation, user will see it first 
     [self.navigationController pushViewController:loginVC animated:YES]; 
    } 
} 

當loginVC完成登錄,也可以提出這樣的問題,確實用戶有一個以上的遊戲嗎?如果不止一個,只彈出一個vc來顯示我們在下面堆疊的SelectGame vc,否則一路彈出。

// LoginVC.m 

// login successful 
if (loggedInUser.games.count > 1) { 
    // it's underneath us, remember? we pushed it before we got here 
    [self.navigationController popViewControllerAnimated:YES]; 
} else { 
    // it's underneath us, but we don't need it, pop all the way back 
    [self.navigationController popToRootViewControllerAnimated:YES]; 
} 

順便說一句,你的NSLog讓我微笑覺得我的老朋友誰常說「authentificated」,而不是「認證」的。

+0

這似乎是一種很好的實施方式。我明天將處理代碼並給你一個更新。哈哈,是的,我有時不斷地添加認證的單詞,而不是使用經過驗證的確切單詞......我想這會讓這個單詞變得更加複雜,我更聰明,但實際上,更多的是無知的哈哈。 – jsetting32

+0

:-)我的好友常常說「驗證」,它聽起來像是「識別」,它是真實的。順便說一句,如果你有一個用戶類,你可以隱藏這個看起來很糟糕的isUserLoggedIn邏輯,用戶名爲 - (BOOL)isLoggedIn; – danh

+0

嘿@danh,所以我想問題是我沒有使用導航堆棧,我只是有多個viewcontrollers在模態dimissed和呈現。有什麼想法?也許這對我來說不可行?因爲我不能實現彈出方法 – jsetting32

相關問題