1

I am currently developing an app that will need to return to another view after running in the background for more than five minutes. In order to do this, I will have to have a timer running in the background after the the Home button has been pressed or in case of an interruptions such as an SMS or a telephone call, then, after five minutes the app will need to go to another view. I know that the applicationDidBecomeActive method will have to be used, but how? I also know that a view can be refreshed in applicationDidBecomeActive but how is that done? ( I am not using storyboards.)

2 Answers2

1

Actually, you should do this with the applicationDidEnterBackground applicationWillEnterForeground delegate methods of UIAppDelegate or by registering to the appropriate system notifications (didBecomeActive is called on other occasions too, such as when a UIAlertView is dismissed from screen).

This should be something in the lines of (may include syntax problems, I'm textbox-coding here):

  • In the viewDidLoad method of your view controller, register to the notifications:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];

  • Implement the willEnterForeground: and didEnterBackground: methods. In willEnterForeground: sample the current time using CACurrentMediaTime() or [NSDate date]. In didEnterBackground: sample the time again and calculate the time difference. Since this method is implemented inside the view controller, you can manipulate the subviews of your self.view as you wish.

  • Do not forget to remove the observers on your dealloc method (viewDidUnload is deprecated since iOS 6.0, so beware):

    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil] [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil]

StatusReport
  • 3,397
  • 1
  • 23
  • 31
0

Here's how you can do it. I just made a test app and I confirm that it works beautifully. Code:

#import "AppDelegate.h"
#import "ViewController.h"
#import "theView.h"

NSTimer *theTimer;
UIViewController *theViewController;
BOOL theTimerFired = NO;

@implementation AppDelegate

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

- (void)applicationWillResignActive:(UIApplication *)application
{   
    // Set a 5 minute timer (300 seconds)
    theTimer = [NSTimer scheduledTimerWithTimeInterval:300.0 target:self selector:@selector(presentVC) userInfo:nil repeats:NO];
}

- (void)presentVC
{
   // Set a boolean to indicate the timer did fire
   theTimerFired = YES;
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{    
    // Check to see if the timer did fire using the previous boolean we created
    if (theTimerFired == YES)
    {
        theViewController = [[UIViewController alloc]initWithNibName:@"theView" bundle:nil];

        [self.viewController presentViewController:theViewController animated:YES completion:NULL];

        [theTimer invalidate];
    }
}

@end
klcjr89
  • 5,862
  • 10
  • 58
  • 91
  • Since the only reason to keep a timer here is to measure the time once you've already gone back to foreground (and not to time tasks while in background, for example), it's better to sample the time at both events instead of using a timer. Also, see [this](http://stackoverflow.com/questions/5187741/nstimer-on-background-is-working) for more information about `NSTimer`s in the background. – StatusReport Jul 20 '13 at 18:28
  • 1
    Thank you so much troop231. What if I want the view to be a different view? (I am sorry for showing my newbieness. – Patricia Cartwright Jul 20 '13 at 19:53
  • It can be whatever view you would like. Just make sure to import the view's header in the AppDelegate. You can replace `theViewController = [[UIViewController alloc]initWithNibName:@"theView" bundle:nil];` with anything you would like. – klcjr89 Jul 20 '13 at 21:13
  • Can you give me an example, please. I have tried doing that and it did nothing. – Patricia Cartwright Jul 20 '13 at 21:23
  • FirstScreen = [[UIViewController alloc]initWithNibName:@"PLCFirstScreenView" bundle:nil]; [self.firstscreen presentViewController:FirstScreen animated:YES completion:NULL]; – Patricia Cartwright Jul 20 '13 at 21:50
  • I need to see your app delegate and view controller code as well. Can you edit your original question above? – klcjr89 Jul 20 '13 at 22:43
  • The name of my app delegate is AppDelegate and the name of the view I would like to app to go to after the applicationdidbecomeactive method is called FirstScreenView.xib – Patricia Cartwright Jul 20 '13 at 23:25
  • Correct, but without seeing the view controller code, it will be hard to tell what's going on. – klcjr89 Jul 20 '13 at 23:42
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33835/discussion-between-patricia-cartwright-and-troop231) – Patricia Cartwright Jul 20 '13 at 23:46