Tieni presente questo caso, quando la tua app è in esecuzione in background e non puoi accedere ai valori archiviati in NSUserDefaults:
Ci sono stati molti thread e bug su questo, ma mi sta succedendo di nuovo in ios 9. Ho un'app che si avvia in background in risposta alle attività NSURLSession e ai push di contenuti disponibili. Riproducibile, se riavvio il telefono e aspetto l'avvio in background della mia app, quando apro l'app scopro che [[NSUserDefaults standardUserDefaults] dictionaryRepresentation] contiene tutti i valori di sistema, ad esempio AppleITunesStoreItemKinds, ecc. Ma non contiene uno qualsiasi dei valori che ho impostato. Se esco forzatamente e riavvio l'app, tutti i miei valori tornano. C'è un modo per evitare che memorizzi nella cache gli standardUserDefaults "vuoti" da prima che il telefono venga sbloccato, o almeno per determinare quando sono incasinati e risolverli senza dover chiudere l'app?
Il problema qui è che NSUserDefaults è in definitiva supportato da un file nel contenitore della tua app e il contenitore della tua app è soggetto alla protezione dei dati. Se non fai nulla di speciale, su iOS 7 e versioni successive, il tuo contenitore utilizza NSFileProtectionCompleteUntilFirstUserAuthentication, un valore ereditato dall'archivio di backup di NSUserDefaults e quindi non puoi accedervi prima del primo sblocco.
IMO il modo migliore per aggirare questo è evitare NSUserDefaults per cose su cui fai affidamento nei percorsi di codice che possono essere eseguiti in background. Memorizza invece queste impostazioni nel tuo file delle preferenze, di cui puoi gestire la protezione dei dati in modo esplicito (in questo caso significa "impostato su NSFileProtectionNone").
Esistono due problemi con NSUserDefaults in un contesto di protezione dei dati:
È un'API completamente astratta: la presenza e l'ubicazione del suo backing store non sono considerate parte di quell'API, quindi non puoi gestirne esplicitamente la protezione dei dati.
Nota Nelle versioni recenti di OS X NSUserDefaults è gestito da un demone e le persone che tentano di manipolare direttamente il suo archivio di backup hanno riscontrato problemi. È facile immaginare lo stesso genere di cose in arrivo su iOS ad un certo punto.
Anche se la modifica della protezione dei dati fosse possibile, NSUserDefaults non ha alcun meccanismo per classificare i dati in base al contesto in cui li stai utilizzando; è un'API "tutto o niente". Nel tuo caso non vuoi rimuovere la protezione da tutte le impostazioni predefinite dell'utente, solo quelle a cui devi accedere in background prima del primo sblocco.
Infine, se qualcuno di questi dati è veramente sensibile, dovresti metterlo nel portachiavi. In particolare, il portachiavi ha la capacità di impostare la protezione dei dati articolo per articolo.