Al preparar su interfaz de usuario para ejecutarse en segundo plano , Apple dice:
Prepare su interfaz de usuario para la instantánea de la aplicación
En algún momento después de que su aplicación ingresa en segundo plano y su método delegado regresa, UIKit toma una instantánea de la interfaz de usuario actual de su aplicación. El sistema muestra la imagen resultante en el selector de aplicaciones. También muestra la imagen temporalmente cuando trae su aplicación de nuevo al primer plano.
La interfaz de usuario de su aplicación no debe contener información confidencial del usuario, como contraseñas o números de tarjetas de crédito. Si su interfaz contiene dicha información, elimínela de sus vistas cuando ingrese al fondo. Además, descarte las alertas, las interfaces temporales y los controladores de vista del sistema que ocultan el contenido de su aplicación. La instantánea representa la interfaz de su aplicación y los usuarios deben poder reconocerla. Cuando su aplicación vuelva al primer plano, puede restaurar los datos y las vistas según corresponda.
Consulte las preguntas y respuestas técnicas QA1838: Cómo evitar que aparezca información confidencial en el selector de tareas
Además de ocultar / reemplazar información confidencial, es posible que también desee decirle a iOS 7 que no tome la instantánea de la pantalla a través de ignoreSnapshotOnNextApplicationLaunch
, cuya documentación dice:
Si cree que la instantánea no puede reflejar correctamente la interfaz de usuario de su aplicación cuando se relanza su aplicación, puede llamar ignoreSnapshotOnNextApplicationLaunch
para evitar que se tome esa instantánea.
Dicho esto, parece que la instantánea de la pantalla todavía se está tomando y, por lo tanto, he presentado un informe de error. Pero debe probar más y ver si usar esta configuración ayuda.
Si se trataba de una aplicación empresarial, es posible que también desee consultar la configuración adecuada que se allowScreenShot
describe en la sección Carga útil de restricciones de la Referencia del perfil de configuración.
Aquí hay una implementación que logra lo que necesitaba. Puede presentar el suyo propio UIImageView
o puede utilizar un patrón de protocolo de delegado para ocultar la información confidencial:
// SecureDelegate.h
#import <Foundation/Foundation.h>
@protocol SecureDelegate <NSObject>
- (void)hide:(id)object;
- (void)show:(id)object;
@end
Luego le di a mi delegado de aplicación una propiedad para eso:
@property (weak, nonatomic) id<SecureDelegate> secureDelegate;
Mi controlador de vista lo configura:
- (void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
delegate.secureDelegate = self;
}
El controlador de vista, obviamente, implementa ese protocolo:
- (void)hide:(id)object
{
self.passwordLabel.alpha = 0.0;
}
- (void)show:(id)object
{
self.passwordLabel.alpha = 1.0;
}
Y, finalmente, el delegado de mi aplicación se sirve de este protocolo y propiedad:
- (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:"];
}
Tenga en cuenta que estoy usando en applicationWillResignActive
lugar de lo recomendado applicationDidEnterBackground
, porque, como han señalado otros, este último no se llama al tocar dos veces el botón de inicio mientras la aplicación se está ejecutando.
Me gustaría poder usar notificaciones para manejar todo esto, en lugar del patrón de protocolo de delegado, pero en mis pruebas limitadas, las notificaciones no se manejan de manera lo suficientemente oportuna, pero el patrón anterior funciona bien.