6

In iOS 7 my app presented an authentication screen when the app went into the background (by subscribing to UIApplicationDidEnterBackgroundNotification). The authentication controller removed sensitive information so the background screenshot did not show any user info. In iOS 8 this does not work anymore. The background screenshot now shows the view the user was last working in and not the authentication controller... even though when the app comes back into the foreground the authentication controller is active.

I found a work around for now. Instead of using UIApplicationDidEnterBackgroundNotification I can use name:UIApplicationWillResignActiveNotification however this causes a flash as the user leaves the app.

Is this a bug or did apple provide a new way to remove sensitive information from views before moving to the background.

Note: putting ignoreSnapshotOnNextApplicationLaunch in applicationWillResignActive: and applicationDidEnterBackground: did not help.

Update: created a bug report

rmaddy
  • 314,917
  • 42
  • 532
  • 579
datinc
  • 3,404
  • 3
  • 24
  • 33
  • I'd file it as a bug with Apple, just to be sure it's not an oversight. Worst case, your bug report is invalid and they'll discard it. – James T Snell Sep 11 '14 at 18:27
  • 2
    Hmmm. My app has always cleared sensitive data when resigning active. Until I read this post I hadn't noticed the "flash" when tapping the Home button from my app under iOS 8. A bug report sounds like a good idea. – rmaddy Sep 11 '14 at 18:31
  • Any word on the bug report? This seems like a huge issue. – SAHM Oct 20 '14 at 20:07
  • Nope... the report has remained unchanged. – datinc Oct 20 '14 at 23:45

3 Answers3

8

Similar approach to @Gurudev0777, but uses UIBlurEffect instead to obscure the content, and doesn't have the downside of worrying about different device screen metrics. Application delegate:

#define MY_BACKGROUND_SCREEN_TAG 1001//or any random but UNIQUE number.

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Visual effect view for blur
    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
    UIVisualEffectView *blurView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    [blurView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
    [blurView setFrame:self.window.frame];
    blurView.tag = MY_BACKGROUND_SCREEN_TAG;

    [self.window addSubview:blurView];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // remove blur view if present
    UIView *view = [self.window viewWithTag:MY_BACKGROUND_SCREEN_TAG];
    if (view != nil)
    {
        [UIView animateWithDuration:0.2f animations:^{
            [view setAlpha:0];

        } completion:^(BOOL finished) {
            [view removeFromSuperview];
        }];
    }
}

works like a charm...

Edited 5/18/2015: Thanks @Simeon Rice for observation about modal dialogs, revised to add blur view to self.window instead of rootViewController.view

Edited 8/23/2016: Thanks @tpankake for observation re: auto-resizing mask.

CSmith
  • 13,318
  • 3
  • 39
  • 42
  • This quality solution unfortunately doesn't blur when a full screen modal is presented (at least on an iPhone) - to work around this, I add the blur view to `self.window` rather than the root view controller's view. – Simon Rice May 15 '15 at 11:07
  • http://stackoverflow.com/questions/18959411/controlling-the-screenshot-in-the-ios-7-multitasking-switcher – TheCodingArt May 18 '15 at 16:28
  • 1
    I like this solution, it works well. One small thing to note. On an iPad if the user hits home and then changes iPad orientation and then accesses the app switcher and selects the blurred application, the blur view will not blur the entire app screenshot due to the orientation change. To fix this, just add auto resizing masks to the blur view `blurView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;` – tpankake Aug 23 '16 at 05:30
  • 2
    Thanks for the solution. We're adding a masking view to our app in applicationWillResignActive: - in iOS 8, when double tapping the home button, it would show the mask right away in the preview. In iOS 9+ (tested in 10 beta too), when double tapping, it does not mask right away. When the app enters the background, then home is double tapped, it's masked. Does anyone know how to make it mask right away? I'm thinking they changed the mechanics in iOS 9 onwards. – John Rogers Sep 07 '16 at 02:58
0
- (void)applicationWillResignActive:(UIApplication *)application
{
   // show splash when app goto background
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.window.bounds];

    imageView.tag = 101; // assign image tag
    //    imageView.backgroundColor = [UIColor redColor];
    [imageView setImage:[UIImage imageNamed:@"Default.png"]];

    [UIApplication.sharedApplication.keyWindow.subviews.lastObject addSubview:imageView];
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
// remove splash when app goto foreground
    UIImageView *imageView = (UIImageView *)[UIApplication.sharedApplication.keyWindow.subviews.lastObject viewWithTag:101]; // lookup image by image tag
    [imageView removeFromSuperview];
}
Winters
  • 23
  • 1
  • 6
-1
here we are putting an imageview while the app animate to background -
-(void)applicationWillResignActive:(UIApplication *)application
{
    imageView = [[UIImageView alloc]initWithFrame:[self.window frame]];
    [imageView setImage:[UIImage imageNamed:@"Default@2x.png"]];
    [self.window addSubview:imageView];
}

Here is the code to remove the imageview:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if(imageView != nil) {
        [imageView removeFromSuperview];
        imageView = nil;
    }
}
It is working and tested many times.
*** Please test this scenario into the device not in simulator.
Deepak Kumar
  • 199
  • 1
  • 6