アプリ内でパスワードロック機能を実現する

「アプリ内で無操作状態時にパスワードロックする」といったようなことを実装してみました。
PCで言うところのスクリーンロック機能はiOSにもありますが、基幹系システムのアプリ等の場合はセキュアなものが要求される場合があります。Webの世界ではSessionタイムアウトを利用するのが一般的ですが、これに近い仕掛けをiOSアプリで実装します。


要件

  • タッチ無操作時間が一定時間を超えた時にパスワード入力画面をモーダルで表示する
  • タッチイベントが検知された場合、無操作時間はクリアされる


実装方法
すべてのタッチイベントを検知する必要がありますが、おそらくUIWindow#setEvent: が一番適した位置かと思いますので、UIWindowを継承した自前のWindowを作成してタップイベントを検知し、タップの度にタイマーの時間を更新するようにします。


LTWindow

@implementation LTWindow

static NSTimeInterval secInterval = 5.0f;

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self resetTimer];
    }
    return self;
}

- (void)sendEvent:(UIEvent *)event {
    [self resetTimer];
    [super sendEvent:event];
}

- (void)resetTimer {
    [_checkExpireTimer invalidate];
    _checkExpireTimer = [NSTimerscheduledTimerWithTimeInterval:secInterval 
                                                         target:self 
                                                       selector:@selector(expire) 
                                                       userInfo:nil 
                                                        repeats:NO];
}

- (void)expire {
    [self resetTimer];
    [(LTAppDelegate *)[[UIApplicationsharedApplication] delegate] lockScreen];
}

@end

LTAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[[LTWindowalloc] initWithFrame:[[UIScreenmainScreen] bounds]] autorelease];
    self.viewController = [[[LTViewController alloc] initWithNibName:@"LTViewController" bundle:nil] autorelease];    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)lockScreen {
    if (!_viewController.presentedViewController) {
        id ctl = [[[LTLockViewControlleralloc] init] autorelease];
        [_viewController presentModalViewController:ctl animated:YES];
    }
}


ダウンロード
サンプルコードをGithubにアップしてますので試してみたい方はご利用ください。
https://github.com/hmori/LockTest


UIWebViewのハンドリングもUIWindowのsetEventが利用できます。色々と便利なのでUIWindowは普段から拡張しておいてもいいのかもしれません。