Prevent iOS from taking screen capture of app before going into background

霸气de小男生 提交于 2019-11-27 11:08:14
Ole Begemann

You are on the right track. This is Apple's recommended way to do this as noted in the iOS Application Programming Guide:

Remove sensitive information from views before moving to the background. When an application transitions to the background, the system takes a snapshot of the application’s main window, which it then presents briefly when transitioning your application back to the foreground. Before returning from your applicationDidEnterBackground: method, you should hide or obscure passwords and other sensitive personal information that might be captured as part of the snapshot.

Deepak Kumar

Need to write the code in Application life cycle methods, 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:@"Splash_Screen.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 properly tested.

I came across the same issue, and my research has lead me to the following answers:

  • set a blurry screen overlay before the app goes in the background and once the app becomes active remove this overlay

  • if it is iOS 7 or later you can use the function ignoreSnapshotOnNextApplicationLaunch

See in apple documentation: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/ignoreSnapshotOnNextApplicationLaunch

I hope this helps somebody.

Your approach is exactly the correct and only way to do it. Place an overlay view and remove it later. It is valid to do this if your app shows sensitive data that you don't want to be cached in image format anywhere.

Apple Doc https://developer.apple.com/library/archive/qa/qa1838/_index.html

Note: Your implementation of -applicationDidEnterBackground: should not start any animations (pass NO to any animated: parameter). The snapshot of your application's window is captured immediately upon returning from this method. Animations will not complete before the snapshot is taken.

Converted Apple code in swift 4.2 App delegate i declared

func applicationDidEnterBackground(_ application: UIApplication) {
    // Your application can present a full screen modal view controller to
    // cover its contents when it moves into the background. If your
    // application requires a password unlock when it retuns to the
    // foreground, present your lock screen or authentication view controller here.

    let blankViewController = UIViewController()
    blankViewController.view.backgroundColor = UIColor.black

    // Pass NO for the animated parameter. Any animation will not complete
    // before the snapshot is taken.
    window.rootViewController?.present(blankViewController, animated: false)
}

func applicationWillEnterForeground(_ application: UIApplication) {
    // This should be omitted if your application presented a lock screen
    // in -applicationDidEnterBackground:
    window.rootViewController?.dismiss(animated: false) false
}

Improvement in Depak Kumar post : Make a property UIImage *snapShotOfSplash;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] ignoreSnapshotOnNextApplicationLaunch];
snapShotOfSplash =[UIImage imageNamed:@"splash_logo"];
}

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


    self.overlayView = [[UIImageView alloc]initWithFrame:[self.window frame]];
    self.overlayView.backgroundColor = [UIColor whiteColor];
    [self.overlayView setImage:snapShotOfSplash];
    [self.overlayView setContentMode:UIViewContentModeCenter];
    [self.window addSubview:self.overlayView];
    [self.window bringSubviewToFront:self.overlayView]; }

- (void)applicationDidBecomeActive:(UIApplication *)application {
if(self.overlayView != nil) {
        [self.overlayView removeFromSuperview];
        self.overlayView = nil;
    }
}
Michael Bazzoni

In iOS 7 you could use the allowScreenShot to stop the ability all together.

See: Apple Developer: Configuration Profile Reference:

allowScreenShot


Boolean
Optional. If set to false, users can’t save a screenshot of the display and are prevented from capturing a screen recording; it also prevents the Classroom app from observing remote screens. Defaults to true.

Availability: Updated in iOS 9.0 to include screen recordings.

Working methods in AppDelegate, swift 4.2:

func blurScreen(style: UIBlurEffect.Style = UIBlurEffect.Style.regular) {
    screen = UIScreen.main.snapshotView(afterScreenUpdates: false)
    let blurEffect = UIBlurEffect(style: style)
    let blurBackground = UIVisualEffectView(effect: blurEffect)
    screen?.addSubview(blurBackground)
    blurBackground.frame = (screen?.frame)!
    window?.addSubview(screen!)
}

func removeBlurScreen() {
    screen?.removeFromSuperview()
}

Where is:

weak var screen : UIView? = nil // property of the AppDelegate

Call these methods in needed delegate methods:

func applicationWillResignActive(_ application: UIApplication) {
    blurScreen()
}

func applicationDidBecomeActive(_ application: UIApplication) {
    removeBlurScreen()
}

Implementation with some animation while going in background and reverse action

   - (void)applicationWillResignActive:(UIApplication *)application
{
     //     fill screen with our own colour
        UIView *colourView = [[UIView alloc]initWithFrame:self.window.frame];
        colourView.backgroundColor = [UIColor blackColor];
        colourView.tag = 1111;
        colourView.alpha = 0;
        [self.window addSubview:colourView];
        [self.window bringSubviewToFront:colourView];

        // fade in the view
        [UIView animateWithDuration:0.5 animations:^{
            colourView.alpha = 1;
        }];

}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // grab a reference to our coloured view
    UIView *colourView = [self.window viewWithTag:1111];
    // fade away colour view from main view
    [UIView animateWithDuration:0.5 animations:^{
        colourView.alpha = 0;
    } completion:^(BOOL finished) {
        // remove when finished fading
        [colourView removeFromSuperview];
    }];

 }

swift 4.0 version.

for use custom icon

first add this line at top of AppDelegate

var imageView: UIImageView?

and add this:

func applicationDidEnterBackground(_ application: UIApplication) {
    imageView = UIImageView(frame: window!.frame)
    imageView?.image = UIImage(named: "AppIcon")
    window?.addSubview(imageView!)
}

func applicationWillEnterForeground(_ application: UIApplication) {
    if imageView != nil {
        imageView?.removeFromSuperview()
        imageView = nil
    }
}

background with black color

func applicationDidEnterBackground(_ application: UIApplication) {
    let blankViewController = UIViewController()
    blankViewController.view.backgroundColor = UIColor.black
    window?.rootViewController?.present(blankViewController, animated: false)
}

func applicationWillEnterForeground(_ application: UIApplication) {
    window?.rootViewController?.dismiss(animated: false)
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!