В разделе «Подготовка пользовательского интерфейса к работе в фоновом режиме» Apple говорит:
Подготовьте свой пользовательский интерфейс для снимка приложения
В какой-то момент после того, как ваше приложение переходит в фоновый режим и возвращается ваш метод делегата, UIKit делает снимок текущего пользовательского интерфейса вашего приложения. Система отображает получившееся изображение в переключателе приложений. Он также временно отображает изображение при возврате вашего приложения на передний план.
Пользовательский интерфейс вашего приложения не должен содержать конфиденциальную информацию о пользователе, например пароли или номера кредитных карт. Если ваш интерфейс содержит такую информацию, удалите ее из окон при входе в фоновый режим. Кроме того, отклоните предупреждения, временные интерфейсы и контроллеры системного представления, которые скрывают содержимое вашего приложения. Снимок представляет интерфейс вашего приложения и должен быть узнаваем для пользователей. Когда ваше приложение возвращается на передний план, вы можете восстанавливать данные и представления по мере необходимости.
См. Технические вопросы и ответы QA1838: Предотвращение появления конфиденциальной информации в переключателе задач
В дополнение к скрытию / замене конфиденциальной информации вы также можете указать iOS 7 не делать снимок экрана через ignoreSnapshotOnNextApplicationLaunch
, чья документация гласит:
Если вы чувствуете, что моментальный снимок не может правильно отражать пользовательский интерфейс вашего приложения при его перезапуске, вы можете позвонить, ignoreSnapshotOnNextApplicationLaunch
чтобы предотвратить создание этого снимка.
Сказав это, похоже, что снимок экрана все еще сделан, и поэтому я отправил отчет об ошибке. Но вам следует продолжить тестирование и посмотреть, помогает ли использование этого параметра.
Если это приложение предприятие, вы также можете посмотреть в соответствующей обстановке allowScreenShot
изложенных в Ограничения Payload разделе Configuration Profile Reference.
Вот реализация, которая дает то, что мне нужно. Вы можете представить свой собственный 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
, потому что, как указывали другие, последний не вызывается при двойном нажатии на кнопку «Домой» во время работы приложения.
Я хотел бы использовать уведомления для обработки всего этого, а не шаблон делегат-протокол, но в моем ограниченном тестировании уведомления не обрабатываются достаточно своевременно, но вышеуказанный шаблон работает нормально.