2012-01-17 55 views
3

我想實現我的應用程序一個密碼鎖功能,讓用戶選擇所需的再入(類似於密碼之前多少時間必須通過一定時間後終止的後臺程序OS的密碼功能)。因此,例如,用戶可能能夠選擇他們希望在將應用程序退出後臺5,10,20分鐘後需要密碼。的iOS:時間

我試過用不同的方式來呈現一個密碼視圖,但通常很難找出呈現它的最佳方式,所以我有這樣的想法,也許最好是在終止應用之後時間到了,因此我只需要在應用程序啓動時展示密碼屏幕。

這可能嗎?我有兩種想法來解決這個問題。

1)在應用程序委託中有NSTimer,當應用程序進入後臺時啓動它,然後當/如果計時器達到設定的分鐘數時啓動它,然後終止應用程序?例如,如果操作系統終止應用程序,以便在計時器完成時更快地釋放內存,我可以看到許多事情出錯。雖然這不是一個大問題。

2)時,應用程序進入後臺設置的NSDate的一個實例。然後,當應用程序啓動時,查看該日期是否超過x分鐘前,並根據該情況提供密碼輸入屏幕。

我覺得這兩個都有點過。我對定時器,RunLoops等沒有經驗,因此任何建議都是值得讚賞的。

+1

你可以在你的計時器中進行一個exit()調用...不是由蘋果指南推薦的,但它可以工作。 – 2012-01-17 12:55:02

+0

考慮當您的應用程序處於後臺時,您選擇的方法如何與用戶在設備上更改當前日期和時間進行交互。有很多應用程序的安全性可以通過這種方式繞過。 – 2012-01-17 17:21:57

回答

2

選項2似乎是,我們已經成功使用一個很好的解決方案。

2

選項2.使用ApplicationDelegate生命週期的方法來驅動它。

  • 應用中:didFinishLaunchingWithOptions:
  • applicationDidBecomeActive:
  • applicationWillResignActive:
  • applicationDidEnterBackground:
  • applicationWillEnterForeground:
  • applicationWillTerminate:
  • 的applicationDidFinishLaunching:

在applicationWillResignActive方法中,將當前時間戳保存到您的UserDefaults中,並在ApplicationWillEnterForeground中對照當前時間進行檢查,並且如果密碼間隔已過,則顯示您的密碼。 (可能最好清除活動時的時間戳,以最大限度地減少在接聽電話和短信等時發生錯誤觸發的機會)

根據敏感度,您可能希望在進入前景之前準備好您的視圖以遮蔽敏感數據,因此它們不要在解鎖狀態下返回。

+0

謝謝@Kevin。這是我正在做的更輕和更好的選擇。 – darkheartfelt 2014-01-25 22:58:56

1

你可以按照兩個更好的結果。例如,當應用程序從didFinishLaunchingWithOptions激活時使用選項2:以及從 啓用應用程序時的選項1 - (void)applicationDidBecomeActive:(UIApplication *)application或 - (void)applicationWillEnterForeground:(UIApplication *)應用程序 選項1--最簡單的方法是在後臺運行循環中安排NSTimer。我建議您的應用程序委託實現以下代碼,並從applicationWillResignActive調用setupTimer :.

- (void)applicationWillResignActive:(UIApplication *)application 
{ 
[self performSelectorInBackground:@selector(setupTimerThread) withObject:nil]; 
} 
-(void)setupTimerThread; 
{ 
  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 
  NSTimer* timer = [NSTimer timerWithTimeInterval:10 * 60 target:self selector:@selector(triggerTimer:) userInfo:nil repeats:YES]; 
  NSRunLoop* runLoop = [NSRunLoop currentRunLoop]; 
  [runLoop addTimer:timer forModes:NSRunLoopCommonModes]; 
  [runLoop run]; 
  [pool release]; 
} 

-(void)triggerTimer:(NSTimer*)timer; 
{ 
  // Do your stuff 
} 
中的appDelegate

.H

中的appDelegate .M

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 

UIApplication* app = [UIApplication sharedApplication]; 

// Request permission to run in the background. Provide an 
// expiration handler in case the task runs long. 
NSAssert(bgTask == UIBackgroundTaskInvalid, nil); 

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
    // Synchronize the cleanup call on the main thread in case 
    // the task actually finishes at around the same time. 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if (bgTask != UIBackgroundTaskInvalid) 
     { 
      [app endBackgroundTask:bgTask]; 
      bgTask = UIBackgroundTaskInvalid; 

     } 
    }); 
}]; 

// Start the long-running task and return immediately. 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    // Do the work associated with the task. 

    // Synchronize the cleanup call on the main thread in case 
    // the expiration handler is fired at the same time. 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if (bgTask != UIBackgroundTaskInvalid) 
     { 
      [app endBackgroundTask:bgTask]; 
      bgTask = UIBackgroundTaskInvalid; 

     } 
    }); 
}); 
NSLog(@"app entering background"); 
/* 
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
*/ 

}
或者你可以在後臺線程通過像這樣運行的NSTimer(我

UIBackgroundTaskIdentifier bgTask; 

我故意漏出線程對象):

-(void)startTimerThread; 
{ 
  NSThread* thread = [[NSThread alloc] initWithTarget:self selector:@selector(setupTimerThread) withObject:nil]; 
  [thread start]; 
} 

嘗試使用上面的代碼。我們使用這兩個選項對我們來說工作正常。祝你好運