ではバックグラウンドで実行するようにUIを準備、アップルは言います:
アプリのスナップショット用にUIを準備する
アプリがバックグラウンドに入り、デリゲートメソッドが戻った後のある時点で、UIKitはアプリの現在のユーザーインターフェイスのスナップショットを取得します。システムは結果の画像をアプリスイッチャーに表示します。また、アプリをフォアグラウンドに戻すときに、画像を一時的に表示します。
アプリのUIには、パスワードやクレジットカード番号などの機密性の高いユーザー情報を含めないでください。インターフェイスにそのような情報が含まれている場合は、背景に入るときにビューから削除してください。また、アプリのコンテンツを不明瞭にするアラート、一時的なインターフェイス、およびシステムビューコントローラーを閉じます。スナップショットはアプリのインターフェースを表し、ユーザーが認識できる必要があります。アプリがフォアグラウンドに戻ったら、必要に応じてデータとビューを復元できます。
テクニカルQ&A QA1838:機密情報がタスクスイッチャーに表示されないようにするを参照してください
機密情報を覆い隠す/置き換えることに加えて、iOS 7にを介して画面のスナップショットを取得しないように指示することもできますignoreSnapshotOnNextApplicationLaunch
。
アプリの再起動時にスナップショットがアプリのユーザーインターフェースを正しく反映できないと思われる場合は、を呼び出しignoreSnapshotOnNextApplicationLaunch
て、スナップショットイメージが取得されないようにすることができます。
そうは言っても、画面のスナップショットはまだ取得されているようです。そのため、バグレポートを提出しました。ただし、さらにテストして、この設定を使用すると効果があるかどうかを確認する必要があります。
これがエンタープライズアプリの場合は、構成プロファイルリファレンスの制限ペイロードセクションでallowScreenShot
概説されているの適切な設定を確認することもできます。
ここに私が必要とするものを実現する実装があります。独自のを提示したりUIImageView
、デリゲートプロトコルパターンを使用して機密情報を覆い隠したりできます。
// SecureDelegate.h
#import <Foundation/Foundation.h>
@protocol SecureDelegate <NSObject>
- (void)hide:(id)object;
- (void)show:(id)object;
@end
次に、アプリのデリゲートにそのプロパティを与えました。
@property (weak, nonatomic) id<SecureDelegate> secureDelegate;
私のビューコントローラーはそれを設定します:
- (void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
delegate.secureDelegate = self;
}
ビューコントローラは明らかにそのプロトコルを実装しています:
- (void)hide:(id)object
{
self.passwordLabel.alpha = 0.0;
}
- (void)show:(id)object
{
self.passwordLabel.alpha = 1.0;
}
そして最後に、私のアプリデリゲートはこのプロトコルとプロパティを利用します。
- (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:"];
}
他の人が指摘したように、アプリの実行中にホームボタンをダブルタップしても後者は呼び出されないため、私はapplicationWillResignActive
推奨applicationDidEnterBackground
ではなくを使用しています。
デリゲートプロトコルのパターンではなく、通知を使用してこれをすべて処理できるようにしたいのですが、限られたテストでは、通知はタイムリーに十分に処理されませんが、上記のパターンは正常に機能します。