Tag Archives: AppDelegate

How to kill your app when it enters background mode

By default, any iOS app we create with Xcode automatically continues running for a short period of time, even if the user puts it in the background and launches a new app. You can even prolong the background execution of an app if your app needs it (for example, finish downloads or long running calculations).

But not all apps need this capability. In fact, if we want to be really nice, we can opt out app in to terminate when it hits the background. It’s really easy to do too: all we need to add is a boolean value into our Info.plist file. It’s called UIApplicationExitsOnSuspend.

Set it to YES and our app terminates as soon as someone presses the home button.

Screen Shot 2015-11-06 at 23.26.02

To add the key, either select your Info.plist file, or head over to your target and click the Info tab at the top (see screenshot).

This is a plist editor, and if you’re not familiar with how to use it, let me introduce you to one of the worst examples of UI design ever – Apple Style:

  • hover over the Key column until you see those little +/- icons come up
  • select the plus icon to add another row
  • double-click the Key part if your row until you can type something in
  • type “UIApplicationExistsOnSuspend” and see it turn into the text “Application does not run in background mode”
  • notice that the type column has changed into Boolean
  • in the Value column, on the far right, find two arrows and change the value to YES
  • that’s it!

Termination Testing

The easiest way to test if this is working is to add a couple of log messages to your AppDelegate file. Find the method stubs for applicationDidEnterBackground and applicationWillTerminate and write yourself a message:

The first method will be called with or without the magic termination key. But the second method will only be called if the app is purged from memory. If you set the key correctly, both methods should be called.

Note that even though the app is killed, it is still visible when you double-tap the home key – but it no longer occupies any memory, nor will it continue to run in the background. As far as I know, this behaviour can only be changed by the user swiping up on an app after a double-tap, or by a hard reset of iOS (hold CTRL+HOME until the Apple Loog appears).

How to control the Preview Screenshot in the iOS Multitasking Switcher

screenshot

Since iOS 7, when you double-tap the home button, little preview screens are shown above the app icon. Swipe them up and the app is closed. Those preview screens are not live though, they’re simple screenshots that iOS takes before sending an app into the background.

Sometimes it’s not desirable to display confidential information on those preview screens. There is no real way to prevent iOS from taking those screenshots, but it’s easy to detect when an app is sent to the background and quickly change our display before this happens. That way the screenshot is taken of something that we can control.

Method 1: crude yet simple

In its simplest form we could just hide the main window when this happens, and bring it back when the app enters the foreground. We’ll do this in our AppDelegate.m, in applicationWillResignActive and applicationDidBecomeActive respectively:

This will result in our app showing a black screen instead of our “real” content.

Method 2: elegant and subtle

The problem with the above approach is that the transition between the black screen and our app’s content is a plain cut, and because everything else in iOS transitions nicely with fades and slides, the cut looks a little out of place.

One solution is to create our own UIView and overlay our interface with it. UIViews can be faded in and out thanks to their alpha values and a UIView singleton. As an added benefit we get to choose which colour we’d like our screen to be – just in case black isn’t desirable. Let’s use white instead:

This looks more complicated than it really is: in the first method we’ll create a standard UIView called colourView and give it the colour of our choice. We’ll also set the alpha value to 0 so it’s transparent. Since we won’t have a reference to this view we’ll give it a tag so we can identify and fade it out again later. 1234 is completely arbitrary – pick your favourite integer here.

As we bring up the view and add it to the main window’s view it’s invisible. animateWithDuration will fade it in over the course of 0.5 seconds, resulting in a subtle fade in. Now we’ll see white and iOS takes a screenshot – no cuts, no popping.

When we get back from the background we’ll first grab a reference to our view – thanks to the arbitrary tag this is really easy. Next we’ll use the same animateWithDuration method and fade the alpha value back to 0 over the course of 0.5 seconds. Longer durations work fine here too, but anything over 2 seconds gives the impression of lag and slowness.

The animateWithDuration comes in two flavours, one of which gives us a completion block so we can execute code when the fade is done. We’ll take this opportunity to remove our view rather than let it linger there in its transparent appearance.

Method 3: bring your own picture

If a solid colour is not snazzy enough we can replace the UIView with a UIImageView and initialise it with a snazzy picture:

The fade out method is the same. You may need to check device orientation and size here to provide a picture that covers the entire view, or use one that’s 2048×2048 to be on the safe side.

Many developers (including PayPal) choose to grab a screenshot of your app manually at this point and apply a blur effect as if the screenshot is presented through frosted glass.

Demo Project

I’ve added a sample project to GitHub so you can see the above in action: