1. ホーム
  2. アイオス

[解決済み】Storyboardのログイン画面のベストプラクティス、ログアウト時のデータクリアの処理について

2022-03-31 03:21:31

質問

Storyboardを使ってiOSアプリを作っています。ルートビューコントローラーは、タブバーコントローラーです。ログイン/ログアウト処理を作成しており、ほぼ正常に動作していますが、いくつかの問題があります。私はこれをすべてセットアップするための最良の方法を知る必要があります。

次のことを実現したい。

  1. アプリの初回起動時にログイン画面を表示する。ログインしたら、タブバーコントローラーの最初のタブに移動する。
  2. その後、アプリを起動するたびに、ログインしているかどうかを確認し、ルート Tab Bar Controller の最初のタブに直接スキップします。
  3. ログアウトボタンを手動でクリックした場合、ログイン画面を表示し、ビューコントローラーのデータをすべてクリアします。

これまでのところ、ルートビューコントローラーをタブバーコントローラーに設定し、ログインビューコントローラーへのカスタムセグエを作成しています。タブバーコントローラクラス内では、ログインしているかどうかを viewDidAppear メソッドを実行し、セグエを実行します。 [self performSegueWithIdentifier:@"pushLogin" sender:self];

また、ログアウトのアクションを実行する必要がある場合の通知も設定しました。 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(logoutAccount) name:@"logoutAccount" object:nil];

ログアウト時に、キーチェインから認証情報をクリアし、以下のコマンドを実行します。 [self setSelectedIndex:0] を実行し、ログインビューコントローラを再度表示するセグエを実行します。

これはすべてうまくいくのですが、気になることがあります。 このロジックはAppDelegateにあるべきでしょうか? また、2つの問題があります。

  • 初めてアプリを起動したとき の場合、セグエが実行される前にタブバーコントローラーが短く表示されます。このコードを viewWillAppear が、そんなに早くからセグエが機能するわけがない。
  • ログアウトしても、すべてのデータはすべてのビューコントローラー内に残っています。新しいアカウントにログインした場合、更新されるまで古いアカウントのデータが表示されたままです。 ログアウト時にこれを簡単にクリアする方法が必要です。

これを作り直すことは可能です。ログイン画面をルートビューコントローラにしたり、AppDelegateにナビゲーションコントローラを作って全てを処理することも考えたのですが...。ただ、現時点では何がベストな方法なのかはわかりません。

解決方法は?

結局、すべてを達成するためにやったことは以下の通りです。これに加えて考える必要があるのは、(a)ログイン処理と、(b)アプリのデータを保存する場所(今回はシングルトンを使用)です。

見ての通り、ルートビューコントローラーは私の メインタブコントローラー . これは、ユーザーがログインした後、アプリが最初のタブに直接起動するようにしたいからです。(これにより、ログイン画面が一時的に表示されるフリッカーを回避することができます)。

AppDelegate.m

このファイルでは、ユーザーがすでにログインしているかどうかをチェックしています。もしそうでなければ、ログインビューコントローラーをプッシュしています。また、ログアウトの処理も行い、データをクリアしてログインビューを表示します。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    // Show login view if not logged in already
    if(![AppData isLoggedIn]) {
        [self showLoginScreen:NO];
    }

    return YES;
}

-(void) showLoginScreen:(BOOL)animated
{

    // Get login screen from storyboard and present it
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    LoginViewController *viewController = (LoginViewController *)[storyboard instantiateViewControllerWithIdentifier:@"loginScreen"];
    [self.window makeKeyAndVisible];
    [self.window.rootViewController presentViewController:viewController
                                             animated:animated
                                           completion:nil];
}

-(void) logout
{
    // Remove data from singleton (where all my app data is stored)
    [AppData clearData];

   // Reset view controller (this will quickly clear all the views)
   UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
   MainTabControllerViewController *viewController = (MainTabControllerViewController *)[storyboard instantiateViewControllerWithIdentifier:@"mainView"];
   [self.window setRootViewController:viewController];

   // Show login screen
   [self showLoginScreen:NO];

}

LoginViewController.m

ここでは、ログインに成功した場合、単にビューを閉じて通知を送信しています。

-(void) loginWasSuccessful
{

     // Send notification
     [[NSNotificationCenter defaultCenter] postNotificationName:@"loginSuccessful" object:self];

     // Dismiss login screen
     [self dismissViewControllerAnimated:YES completion:nil];

}