1

現在、iOS アプリケーションで問題が発生しています。
段階的なログイン パターンを取り入れようとしています。つまり、ユーザーはログインを必要とせずにアプリの一部にアクセスできます。

必要な機能は次のとおりです。

  • ユーザーはいつでも、ログインが必要なすべてのナビゲーション項目を表示できます
  • ユーザーがログインが必要な uiview(controller) にアクセスしようとすると、ログインを求める UIAlertView が表示されます (できれば、開始されたセグエの宛先が制限されていることをアプリが認識したときに、UIAlertView が表示されることをお勧めします)。

最初に、指定された初期化子 (initWithCoder) で NSUserDefaults をチェックして、ユーザーがログインしているかどうかを確認する UIViewController のサブクラスを使用しました。その後、それをサブクラス化しました。制限事項は次のとおりです。

  • UIViewController の他のサブクラス、つまり UITableViewController を使用できませんでした
  • ビューが表示された後に UIAlertView が表示されましたが、サブクラス化された UIViewController がユーザーがログインしていると想定した場合、エラーが発生すると想定しています。

質問の概要:
ユーザーが特定の UIView(Controller) および UIViewController のサブクラスにアクセスすることを条件付きで防止する方法を知りたいです。

Update 1
カテゴリやプロトコルは実行可能な解決策になるでしょうか?

Update 2
CodaFi は、ユーザーの状態を管理する優れたソリューションとしてシングルトンを指摘しました。

これを実装したら、ユーザーのアクセスを制御する方法を理解する必要があります。
私はストーリーボードを使用しているので、最も用途の広い実装は UIStoryboardSegue をサブクラス化することであり、ユーザーが制限された UIViewController にアクセスしようとしているかどうかを実行メソッドで確認します (おそらく制限されたコントローラーには、必要なステータスを指定するプロトコル プロパティがあります: ログイン/アウト)。ただし、ここでの落とし穴は、ストーリーボード グラフィック エディターで UIStoryboardSegue のクラス/サブクラスを選択できないことです。私はプログラムでそれを行うことができることを認識していますが、IBActions を追加し、セグエを実行するメソッドにそのようなものを追加する必要があるため、退屈に思えます。

ユーザーのナビゲーションを制限するための実行可能な解決策はありますか?

更新 3
この質問に回答を追加しましたが、私が書いた回答ではナビゲーション バー コントローラー間のセグエが考慮されていないため、未回答と見なします。ただし、一部の人には役立つ場合があります。

4

2 に答える 2

2

それで、カスタムセグエを使用してこれを行う方法に答えました。

今、私の本当の問題は、tabbarcontrollerdelegate プロトコルとの精神的な切断であることがわかりました。

タブへのアクセスを防ぐための解決策として、上記のタブバーコントローラーを処理するクラスを作成しました

#import <Foundation/Foundation.h>

@interface TabBarDelegate : NSObject<UITabBarControllerDelegate,UIAlertViewDelegate>{
    UITabBarController *cachedTabBarController;
}

@end

#import "TabBarDelegate.h"

@implementation TabBarDelegate

-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
    NSLog(@"%s",__FUNCTION__);
    NSLog(@"Pretending the user isnt logged in");

    if(true){
        NSString *message = [NSString stringWithFormat:@"You require an account to access %@",viewController.tabBarItem.title];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Account Required" message:message delegate:self cancelButtonTitle:@"Okay" otherButtonTitles: @"Login",@"Create Account",nil];
        [alert show];
        //Hold tabbarcontroller property for alert callback
        cachedTabBarController = tabBarController;
        return false;
    }

    return true;
}

-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
    if(cachedTabBarController){
        switch (buttonIndex) {
            case 1:
                //Login
                [cachedTabBarController performSegueWithIdentifier:@"tabBarToLogin" sender:cachedTabBarController];
                break;
            case 2:
                //Sign up
                [cachedTabBarController performSegueWithIdentifier:@"tabBarToSignup" sender:cachedTabBarController];
                break;
            default:
                break;
        }
        //Release tab bar controller from memory
        cachedTabBarController = nil;
    }
}

@end

次に、applicationDidFinishLaunching の appDelegate に配線しました...

//Hook up tab bar delegate
    mainTabController = (UITabBarController*)self.window.rootViewController;
    mainTabBarDelegate = [[TabBarDelegate alloc] init];
    mainTabController.delegate = mainTabBarDelegate;

そして出来上がり

于 2012-04-27T04:47:50.743 に答える
0

さて、私は解決策の一部を持っています。

カスタム セグエを選択できる状況でのみ機能します (また、モーダルではなく、プッシュ用のコードのみを記述しています)。

認証を必要とするすべてのコントローラのプロトコル「UIViewControllerAuthentication」。このプロトコルには、必要な認証ステータスを取得するメソッドが含まれています。

enum authenticationStatus {
notLoggedIn = 0,
noPassword = 1,
loggedIn = 2
};

@protocol UIViewControllerAuthentication <NSObject>

-(enum authenticationStatus)authStatusRequired;

@end

認証を必要とするコントローラーは、次のプロトコルに準拠しています。

-(enum authenticationStatus)authStatusRequired{
return loggedIn;
}

次に、これを認証済みプッシュ セグエに使用します

@interface SeguePushWithAuth : UIStoryboardSegue

@end
-(void)perform{
    NSLog(@"custom segue destination : %@",self.destinationViewController);
    NSLog(@"custom segue source : %@",self.sourceViewController);
    NSLog(@"custom segue dest conforms to protocol : %i",[self.destinationViewController conformsToProtocol:@protocol(UIViewControllerAuthentication)]);

    if([self.destinationViewController conformsToProtocol:@protocol(UIViewControllerAuthentication)]){
        UIViewController <UIViewControllerAuthentication> *destination = (UIViewController <UIViewControllerAuthentication> *)self.destinationViewController;
        if (!((int)[AccountModel userAuthStatus] >= (int)[destination authStatusRequired])) {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Authentication" message:@"You need an account to access this area" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Login",@"Create Account", nil];
            //alert
            [alert show];
            return;
        }
    }

    [[self.sourceViewController navigationController] pushViewController:self.destinationViewController animated:true];
}

@end

次に、uistoryboard でカスタム セグエを使用します。

これは、宛先コントローラーがセグエをキャンセルできるようにするための適切なパターンです。
ただし、タブバーコントローラーをその子にリンクするセグエを認証できるようにしたいので、私が望むものとはほど遠いです。

于 2012-04-19T14:25:39.873 に答える