En préparant votre interface utilisateur pour qu'elle s'exécute en arrière-plan , Apple déclare:
Préparez votre interface utilisateur pour l'instantané de l'application
À un moment donné, une fois que votre application est entrée en arrière-plan et que votre méthode de délégué est retournée, UIKit prend un instantané de l'interface utilisateur actuelle de votre application. Le système affiche l'image résultante dans le sélecteur d'application. Il affiche également temporairement l'image lorsque vous ramenez votre application au premier plan.
L'interface utilisateur de votre application ne doit contenir aucune information utilisateur sensible, telle que des mots de passe ou des numéros de carte de crédit. Si votre interface contient de telles informations, supprimez-les de vos vues lorsque vous entrez en arrière-plan. En outre, ignorez les alertes, les interfaces temporaires et les contrôleurs de vue système qui masquent le contenu de votre application. L'instantané représente l'interface de votre application et doit être reconnaissable par les utilisateurs. Lorsque votre application revient au premier plan, vous pouvez restaurer les données et les vues selon vos besoins.
Voir Questions et réponses techniques QA1838: Empêcher les informations sensibles d'apparaître dans le sélecteur de tâches
En plus de masquer / remplacer les informations sensibles, vous pouvez également demander à iOS 7 de ne pas prendre l'instantané d'écran via ignoreSnapshotOnNextApplicationLaunch
, dont la documentation dit:
Si vous pensez que l'instantané ne peut pas refléter correctement l'interface utilisateur de votre application lorsque celle-ci est relancée, vous pouvez appeler ignoreSnapshotOnNextApplicationLaunch
pour empêcher la prise de cette image instantanée.
Cela dit, il semble que la capture d'écran soit toujours prise et j'ai donc déposé un rapport de bogue. Mais vous devriez tester plus loin et voir si l'utilisation de ce paramètre aide.
S'il s'agissait d'une application d'entreprise, vous souhaiterez peut-être également examiner le paramètre approprié de allowScreenShot
décrit dans la section Charge utile des restrictions de la référence du profil de configuration.
Voici une mise en œuvre qui réalise ce dont j'avais besoin. Vous pouvez présenter le vôtre UIImageView
ou utiliser un modèle de protocole de délégué pour masquer les informations confidentielles:
// SecureDelegate.h
#import <Foundation/Foundation.h>
@protocol SecureDelegate <NSObject>
- (void)hide:(id)object;
- (void)show:(id)object;
@end
J'ai ensuite donné à mon délégué d'application une propriété pour cela:
@property (weak, nonatomic) id<SecureDelegate> secureDelegate;
Mon contrôleur de vue le définit:
- (void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
delegate.secureDelegate = self;
}
Le contrôleur de vue implémente évidemment ce protocole:
- (void)hide:(id)object
{
self.passwordLabel.alpha = 0.0;
}
- (void)show:(id)object
{
self.passwordLabel.alpha = 1.0;
}
Et, enfin, mon délégué d'application utilise ce protocole et cette propriété:
- (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:"];
}
Notez que j'utilise applicationWillResignActive
plutôt que le conseillé applicationDidEnterBackground
, car, comme d'autres l'ont souligné, ce dernier n'est pas appelé lorsque vous appuyez deux fois sur le bouton d'accueil pendant que l'application est en cours d'exécution.
J'aimerais pouvoir utiliser les notifications pour gérer tout cela, plutôt que le modèle de protocole de délégué, mais dans mes tests limités, les notifications ne sont pas gérées assez rapidement, mais le modèle ci-dessus fonctionne bien.