0

そのため、ユーザーの資格情報に基づいて、ログイン ビューが閉じられた後にアプリのメイン ビューがメイン ビューの上にテーブルビューを表示するか、またはログイン ビューが閉じられました。

したがって、現在、私はトークンを取得するサーバーに http 投稿要求を送信し、その後別の呼び出しを行って、ユーザーが持っているリスト項目の量を取得します。たとえば、ゲームです。

ユーザーが 1 つのゲームしか持っていない場合は、メイン ビューを表示したいのですが、ユーザーが複数のゲームを持っている場合は、ユーザーにテーブルビューが表示され、セルの 1 つを押してから、テーブルビューをモーダルに閉じてメインビューを表示する必要があります。

通常、私はこれらの3つのコントローラーを持っています。少なくともこれは、実装がどうあるべきかについて私が考えている方法であり、正しい方法かどうかはわかりません.

したがって、コントローラー A がログイン、コントローラー B がテーブルビュー、コントローラー C がメインビューであるとします。

コントローラ C はスタックの一番下にあり、コントローラ A は一番上にあります。ただし、コントローラー A からの情報に基づいて、コントローラー B が表示される場合と表示されない場合があります。つまり、ユーザーがまだログインしていない場合、ログイン ビュー (コントローラー 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];
}

メインビュー(viewcontroller C)のviewdidLoadで:

 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];

ログイン ビュー コントローラー (コントローラー 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 (viewcontroller A) の viewDidLoad メソッドでは:

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

これがどのように可能になるかについて、ある種のスキーマまたは絶対確実な理論を教えていただければ、それは素晴らしいことです。

現時点では、メインビューが表示された状態でログインビューを閉じていますが、テーブルビューをモーダル (アニメーション) で表示しているため、望ましくありません。したがって、アニメーションによって 1 つのビューが閉じられ、メインビューが一瞬表示され、アニメーションによってメインビューの上にテーブルビューが表示されることを想像できます。ユーザーがログインし、ゲームを選択して詳細を表示するまで、ユーザーがメインビューを表示することさえ望んでいません。

テーブルビューがビュー A と C の間に表示される唯一の理由は、ユーザーが複数のゲームを持っている可能性があるためですが、ゲームが 1 つしかない場合は、コントローラー A からコントローラー B ではなく、コントローラー A からコントローラー C に移動することを思い出してください。コントローラーCへ。

4

1 に答える 1

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 を 1 つだけポップバックして、下にスタックした 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 は、「認証済み」ではなく「認証済み」と言っていた古い友人のことを考えると、私を笑顔にさせてくれました。

于 2013-07-19T00:49:05.060 に答える