Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
517 views
in Technique[技术] by (71.8m points)

ios7 - Controlling the screenshot in the iOS 7 multitasking switcher

I've been trying to find some information regarding the new multitasking switcher in iOS 7 and especially the screenshot that the OS takes when the app is going into hibernation.

enter image description here

Is there any way to completely turn off this feature or screenshot? Or can I hide the app altogether from the switcher? The app needs to run in the background, but we do not want to show any screenshot from the app.

The screenshot is potentially a security-risk, think along the lines for banking-apps where your card number or account summary will be available to anyone that double-click on the home button on the device.

Anyone with any insight into this? Thanks.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In Preparing Your UI to Run in the Background, Apple says:

Prepare Your UI for the App Snapshot

At some point after your app enters the background and your delegate method returns, UIKit takes a snapshot of your app’s current user interface. The system displays the resulting image in the app switcher. It also displays the image temporarily when bringing your app back to the foreground.

Your app’s UI must not contain any sensitive user information, such as passwords or credit card numbers. If your interface contains such information, remove it from your views when entering the background. Also, dismiss alerts, temporary interfaces, and system view controllers that obscure your app’s content. The snapshot represents your app’s interface and should be recognizable to users. When your app returns to the foreground, you can restore data and views as appropriate.

See Technical Q&A QA1838: Preventing Sensitive Information From Appearing In The Task Switcher

In addition to obscuring/replacing sensitive information, you might also want to tell iOS 7 to not take the screen snapshot via ignoreSnapshotOnNextApplicationLaunch, whose documentation says:

If you feel that the snapshot cannot correctly reflect your app’s user interface when your app is relaunched, you can call ignoreSnapshotOnNextApplicationLaunch to prevent that snapshot image from being taken.

Having said that, it appears that the screen snapshot is still taken and I have therefore filed a bug report. But you should test further and see if using this setting helps.

If this was an enterprise app, you might also want to look into the appropriate setting of allowScreenShot outlined in the Restrictions Payload section of the Configuration Profile Reference.


Here is an implementation that achieves what I needed. You can present your own UIImageView, or your can use a delegate-protocol pattern to obscure the confidential information:

//  SecureDelegate.h

#import <Foundation/Foundation.h>

@protocol SecureDelegate <NSObject>

- (void)hide:(id)object;
- (void)show:(id)object;

@end

I then gave my app delegate a property for that:

@property (weak, nonatomic) id<SecureDelegate> secureDelegate;

My view controller sets it:

- (void)viewDidLoad
{
    [super viewDidLoad];

    AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    delegate.secureDelegate = self;
}

The view controller obviously implements that protocol:

- (void)hide:(id)object
{
    self.passwordLabel.alpha = 0.0;
}

- (void)show:(id)object
{
    self.passwordLabel.alpha = 1.0;
}

And, finally, my app delegate avails itself of this protocol and property:

- (void)applicationWillResignActive:(UIApplication *)application
{
    [application ignoreSnapshotOnNextApplicationLaunch];  // this doesn't appear to work, whether called here or `didFinishLaunchingWithOptions`, but seems prudent to include it

    [self.secureDelegate hide:@"applicationWillResignActive:"];  // you don't need to pass the "object", but it was useful during my testing...
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [self.secureDelegate show:@"applicationDidBecomeActive:"];
}

Note, I'm using applicationWillResignActive rather than the advised applicationDidEnterBackground, because, as others have pointed out, the latter is not called when double tapping on the home button while the app is running.

I wish I could use notifications to handle all of this, rather than the delegate-protocol pattern, but in my limited testing, the notifications aren't handled in a timely-enough manner, but the above pattern works fine.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...