Nel preparare la tua interfaccia utente per l'esecuzione in background , Apple afferma:
Prepara la tua interfaccia utente per l'istantanea dell'app
Ad un certo punto dopo che l'app è entrata in background e il metodo delegato è tornato, UIKit acquisisce un'istantanea dell'interfaccia utente corrente dell'app. Il sistema visualizza l'immagine risultante nel commutatore di app. Inoltre, visualizza temporaneamente l'immagine quando si riporta la tua app in primo piano.
L'interfaccia utente della tua app non deve contenere informazioni sensibili sugli utenti, come password o numeri di carte di credito. Se la tua interfaccia contiene tali informazioni, rimuovile dalle tue visualizzazioni quando inserisci lo sfondo. Inoltre, ignora gli avvisi, le interfacce temporanee e i controller di visualizzazione del sistema che oscurano il contenuto della tua app. L'istantanea rappresenta l'interfaccia della tua app e dovrebbe essere riconoscibile dagli utenti. Quando la tua app torna in primo piano, puoi ripristinare dati e visualizzazioni in base alle esigenze.
Vedere Domande e risposte tecniche QA1838: Come impedire la visualizzazione di informazioni sensibili nel selettore di attività
Oltre a nascondere / sostituire le informazioni sensibili, potresti anche voler dire a iOS 7 di non acquisire l'istantanea dello schermo tramite ignoreSnapshotOnNextApplicationLaunch
, la cui documentazione dice:
Se ritieni che l'istantanea non possa riflettere correttamente l'interfaccia utente della tua app quando l'app viene riavviata, puoi chiamare ignoreSnapshotOnNextApplicationLaunch
per impedire che venga scattata l'immagine dell'istantanea.
Detto questo, sembra che l'istantanea dello schermo sia ancora scattata e quindi ho presentato una segnalazione di bug. Ma dovresti testare ulteriormente e vedere se l'uso di questa impostazione aiuta.
Se si trattava di un'app aziendale, potresti anche voler esaminare l'impostazione appropriata di allowScreenShot
delineata nella sezione Payload delle restrizioni del Riferimento al profilo di configurazione.
Ecco un'implementazione che raggiunge ciò di cui avevo bisogno. Puoi presentare il tuo UIImageView
oppure puoi utilizzare un modello di protocollo delegato per nascondere le informazioni riservate:
// SecureDelegate.h
#import <Foundation/Foundation.h>
@protocol SecureDelegate <NSObject>
- (void)hide:(id)object;
- (void)show:(id)object;
@end
Ho quindi dato alla mia app delegato una proprietà per questo:
@property (weak, nonatomic) id<SecureDelegate> secureDelegate;
Il mio controller di visualizzazione lo imposta:
- (void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
delegate.secureDelegate = self;
}
Il view controller implementa ovviamente quel protocollo:
- (void)hide:(id)object
{
self.passwordLabel.alpha = 0.0;
}
- (void)show:(id)object
{
self.passwordLabel.alpha = 1.0;
}
E, infine, il mio delegato dell'app si avvale di questo protocollo e proprietà:
- (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:"];
}
Nota, sto usando applicationWillResignActive
piuttosto che il consigliato applicationDidEnterBackground
, perché, come altri hanno sottolineato, quest'ultimo non viene chiamato quando si tocca due volte il pulsante home mentre l'app è in esecuzione.
Vorrei poter utilizzare le notifiche per gestire tutto questo, piuttosto che il modello del protocollo delegato, ma nei miei test limitati, le notifiche non vengono gestite in modo abbastanza tempestivo, ma il modello sopra funziona bene.